go 统计目录大小
文件大小获取
// 这里获取的是 FileInfo 对象
fi, _ := os.Stat(filepath)
FileInfo 定义如下:
type FileInfo interface {
Name() string // 文件的名字
Size() int64 // 普通文件返回值表示其大小;其他文件的返回值含义各系统不同
Mode() FileMode // 文件的模式位
ModTime() time.Time // 文件的修改时间
IsDir() bool // 等价于Mode().IsDir()
Sys() interface{} // 底层数据来源(可以返回nil)
}
标准库提供了 filepath.Walk 遍历目录,但是这个函数是串行的,当目录比较多时,性能很差,
这里建议自己实现,大致步骤如下:
- 读取给定目录下所有文件及目录;
- 遍历读取结果,如果是目录,创建协程重复 1;
- 如果是文件,获取大小,保存到 channel 中;
细节
- 用 channel 控制最大协程数量;
- WaitGroup 控制并发;
import (
"flag"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"sync"
"time"
)
//获取目录dir下的文件大小
func walkDir(dir string, wg *sync.WaitGroup, fileSizes chan<- int64) {
defer wg.Done()
for _, entry := range dirents(dir) {
if entry.IsDir() {//目录
wg.Add(1)
subDir := filepath.Join(dir, entry.Name())
go walkDir(subDir, wg, fileSizes)
} else {
fileSizes <- entry.Size()
}
}
}
//sema is a counting semaphore for limiting concurrency in dirents
var sema = make(chan struct{}, 20)
//读取目录dir下的文件信息
func dirents(dir string) []os.FileInfo {
sema <- struct{}{}
defer func() { <-sema }()
entries, err := ioutil.ReadDir(dir)
if err != nil {
fmt.Fprintf(os.Stderr, "du: %v\n", err)
return nil
}
return entries
}
//输出文件数量的大小
func printDiskUsage(nfiles, nbytes int64) {
fmt.Printf("%d files %.1f GB\n", nfiles, float64(nbytes)/1e9)
}
//提供-v 参数会显示程序进度信息
var verbose = flag.Bool("v", false, "show verbose progress messages")
func Start() {
flag.Parse()
roots := flag.Args()//需要统计的目录
if len(roots) == 0 {
roots = []string{"."}
}
fileSizes := make(chan int64)
var wg sync.WaitGroup
for _, root := range roots {
wg.Add(1)
go walkDir(root, &wg, fileSizes)
}
go func() {
wg.Wait() //等待goroutine结束
close(fileSizes)
}()
var tick <-chan time.Time
if *verbose {
tick = time.Tick(100 * time.Millisecond) //输出时间间隔
}
var nfiles, nbytes int64
loop:
for {
select {
case size, ok := <-fileSizes:
if !ok {
break loop
}
nfiles++
nbytes += size
case <-tick:
printDiskUsage(nfiles, nbytes)
}
}
printDiskUsage(nfiles, nbytes)
}
go 统计目录大小的更多相关文章
- PHP文件操作 之统计目录大小
<?php //定义一个函数 统计目录大小函数 function dirSize($dirName) { //判断目录是否存在 if (!file_exists($dirName)) { die ...
- PHP遍历目录返回统计目录大小实例
分享一个 PHP遍历目录并返回统计目录大小的方法.代码: <?php $dirname = "test1"; //mkdir($dirname); //遍历一层目录 func ...
- du 使用详解 linux查看目录大小 linux统计目录大小并排序 查看目录下所有一级子目录文件夹大小 du -h --max-depth=1 |grep [
常用命令 du -h --max-depth=1 |grep [TG] |sort #查找上G和T的目录并排序 du -sh #统计当前目录的大小,以直观方式展现 du -h --max-d ...
- php统计目录大小
function dirSize($directroy) { $dir_size=0; $dir_handle = @opendir($directroy); if($dir_handle) { wh ...
- 使用php递归计算目录大小
统计一个目录大小,因为不知道目录中子目录的深度,所以for循环很难实现,但是用递归调用很容易实现,只要统计出一个目录中所有文件的大小,那么每一次调用就可以了,随便建了个目录,建立一些文件,方法代码如下 ...
- PHP中统计目录中文件以及目录中目录的大小
<?php #循环遍历目录中所有的文件,并统计目录和文件的大小 $dirName="phpMyAdmin"; $dir=opendir($dirName); #返回一 ...
- linux 系统统计目录下文件夹的大小
du -ah --max-depth=1 这个是我想要的结果 a表示显示目录下所有的文件和文件夹(不含子目录),h表示以人类能看懂的方式,max-depth表示目录的深度. du命令用来查看 ...
- 一个统计目录文件大小的php函数
早上刚到公司,头告诉我,抓紧写一个小函数,用来统计指定目录中文件大小,我了个去,动手吧,还好有点小基础,一会就完工了,哈哈.代码在下面咯. <? /** 统计目录文件大小的函数 @author ...
- Linux系统下查看目录大小
转载:http://blog.csdn.net/iamlaosong/article/details/7085178 我们有个系统每天要下载数据,为了检查下载数据是否正常,需要查看下载数据目录大小,因 ...
随机推荐
- dsp实验一 常见问题教程
1.选择合适阅读材料:卖油翁.将进酒,等. 2.录音设备三选一:某种电脑声卡+线上convert/楼月mp3录音软件+格式工厂(我选的)/Matlab (注:这是目前已知的方法,我只用了第二个) 3. ...
- linux 查看/修改jdk版本
linux 查看/修改jdk版本 配置环境变量vim /etc/profile 编辑profile文件 在底部加入JAVA_HOME=/usr/java/jdk1.8PATH=$JAVA_HOME/b ...
- SimpleDateFormat日期格式解析
先看一个代码示例: import java.text.SimpleDateFormat; import java.util.Date; public class test{ public static ...
- 西瓜视频蓝光1080P下载方法
西瓜视频的蓝光画质只能在APP上看,如何获取1080P画质的地址呢? 1.先安装 WinPcap 2.然后安装夜神安卓模拟器NOX 3.NOX模拟器里安装西瓜视频的最新APP,旧版本APP只提供超清模 ...
- Mybatis 笔记
环境:Mybatis 3 +MariaDB 10.1 似乎在调用存储过程时 ,参数只能写在一行上. 否则会返回语法错误.
- ROS启动多launch文件
在ROS工程中经常需要启动好几个launch文件,比较不方便,有下面两种方法可以更高效些: 重写一个大型的launch文件,将所有的节点的启动配置信息都包含进去. 通过bash写一个xxx.sh文件, ...
- Go语言--基础语法笔记
### 换了工作,好久没有添加新文章了,本来是想更新到github上的,想想还是在博客里放着,感觉以前的文章都没有很仔细,都只是问题处理的记录, 以后想新加一些整理的笔记也好 ### 主要内容 2.1 ...
- SQLAlchemy+Flask-RESTful使用(四)
前言 顺利出到4啦,其实学习过程中发现了不少错误,不过有些实在是没啥代表性. 最近买了两本小程序和安卓方面的书,其实从初中开始,想搞编程的目的就是写些安卓软件. 现在看来不太可能了.拿来当当兴趣爱好还 ...
- 初识C语言(二)
C语言标识符的命名规则 变量或者函数起的名字就是标识符,而且C语言的标识符有它自己的命名规则: 标识符的长度最好不要超过8位,因为在一些版本的C语言中标示符的前八位是有效的,所以当两个标识符的前八位相 ...
- 关于Integer比较问题
public class Test { public static void main(String[] args) { Integer a=127; Integer b=127; System.ou ...