您的位置:首页 > 编程语言

Golang代码搜集-访Unix du命令的目录文件数量和文件总大小统计程序

2017-12-31 17:58 1121 查看
这段代码出自《Go程序设计语言》(英文版)第247页,简单的访Unix du命令程序,用于统计某目录的文件数量和总大小,代码演示了如何控制并发数量、输入命令、定时器等。

package main

import (
"os"
"io/ioutil"
"fmt"
"path/filepath"
"time"
"flag"
"sync"
)

func walkDir(dir string,wg *sync.WaitGroup, fileSizes chan<- int64) {
//一个goroutine结束 -1
defer wg.Done()
//获取目录下的文件和文件夹列表
for _, entry := range dirents(dir) {
if entry.IsDir() {
//每启动一个新goroutine则 +1
wg.Add(1)
//拼接子目录路径
subdir := filepath.Join(dir, entry.Name())
//递归子目录
go walkDir(subdir, wg,fileSizes)
} else {
//如果是文件,则累加文件大小
fileSizes <- entry.Size()
}
}
}
// sema是限制dirents并发数量的信号量
var sema = make(chan struct{}, 20)
//获取某目录下的文件和文件夹列表
func dirents(dir string) []os.FileInfo {
sema <- struct{}{} // acquire token
defer func() { <-sema }() // release token
entries, err := ioutil.ReadDir(dir)
if err != nil {
fmt.Fprintf(os.Stderr, "du1:%v\n", err)
return nil
}
return entries
}
//输入参数是否包括 -v
var verbose = flag.Bool("v", false, "show verbose progress messages")
func main() {
//读取输入参数
flag.Parse()
roots := flag.Args()
if len(roots) == 0 {
roots = []string{"."}
}
//记录搜索开始时间
start := time.Now()
//goroutine计数
var wg sync.WaitGroup
fsizes := make(chan int64)
for _, root := range roots {
//每启动一个新goroutine则 +1
wg.Add(1)
go  walkDir(root,&wg, fsizes)
}
go func(){
//等待所有goroutine结束后关闭fsizes
wg.Wait()
close(fsizes)
}()
//声明变量保存 文件总数量和总大小
var nfiles, nbytes int64
//声明定时器,500ms
var tick <-chan time.Time
//输入参数包括 -v,则启用定时器
if *verbose{
tick = time.Tick(500 * time.Millisecond)
}
loop:
for {
select {
case size, ok := <-fsizes:
//当fsizes关闭后,跳出for循环
if !ok {
break loop
}
//fsizes有数据,则累加文件数量和总大小
nfiles ++
nbytes += size
case <-tick:
//定时显示当前进度
printDiskUsage(nfiles, nbytes)
}
}
//显示最终结果
printDiskUsage(nfiles, nbytes)
fmt.Printf("%v", time.Since(start))
}
func printDiskUsage(nfiles, nbytes int64) {
fmt.Printf("%d files %.1f GB\n", nfiles, float64(nbytes)/1e9)
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  golang unix du 定时器
相关文章推荐