Exercise 8.9: Write a du tool that calculates and displays the size of the directory at the root directory every once in a while.
Package Mainimport (//"filepath" "Flag" "FMT" "Io/ioutil" "OS" "Path" "Sync" "Time")///Exercise 8.9: Write a du tool that calculates and displays the size of the directory at the root directory at intervals. *///receive command line arguments-vvar verbose = flag. Bool ("V", False, "show verbose Progress Messages") Func main () {//Receive command line arguments, multiple path flag. Parse () Roots: = Flag. Args ()//If no path is passed, give default value if Len (roots) = = 0 {roots = []string{"/"}} for { Sumfilesize (Roots) time. Sleep (* time). Second)}}func sumfilesize (roots []string) {//Send and receive file byte size channel filesizes: = Make (chan int64) Goroutine counter var n sync. Waitgroup//loop command line delivery path for _, Root: = Range Roots {n.add (1)//start goroutine calculation Go Walkdir (Root, &n, filesizes)}//Start Goroutine, wait for all compute directories Goroutine end go func () { N.wait () Close (fileSizes)} ()//Timed display directory progress sent by channel Var tick <-chan time. Time if *verbose {tick = time. Tick ($ * time). Millisecond)} var nfiles, nbytes Int64//select and loop loop, multiplexed loop:for {Sele CT {case size, OK: = <-filesizes:if!ok {break Loop//filesizes was closed}//Calculate the number of directories, calculate the byte size nfiles+ + nbytes + = size case <-tick://received timed channel print progress Printdiskusage (Nfiles, Nbytes)}}//Last print total Printdiskusage (nfiles, Nbyte s)//Final Totals}func Walkdir (dir string, n *sync. Waitgroup, filesizes chan<-Int64) {defer n.done () for _, Entry: = Range Dirents (dir) {i F entry. Isdir () {N.add (1) SubDir: = path. Join (dir, entry. Name ())//Open multiple goroutine for recursive go walkdir (subdir, N, filesizes) } else {filesizes <-entry. Size ()}}}var sema = Make (chan struct{}, +//Dirents returns the entries of directory Dir.func di Rents (dir string) []os. FileInfo {//Use count semaphore logic limits too much concurrency sema <-struct{}{} entries, err: = Ioutil. ReadDir (dir) <-sema if err! = Nil {fmt. fprintf (OS. Stderr, "DU1:%v\n", err) return nil} return Entries}func printdiskusage (nfiles, Nbytes int6 4) {FMT. Printf ("%d files%.1f gb\n", Nfiles, Float64 (nbytes)/1e9)}
Daily Go Language Bible-Example: Concurrent directory traversal exercises