文件大小获取

// 这里获取的是 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. 读取给定目录下所有文件及目录;
  2. 遍历读取结果,如果是目录,创建协程重复 1;
  3. 如果是文件,获取大小,保存到 channel 中;

细节

  1. 用 channel 控制最大协程数量;
  2. 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 统计目录大小的更多相关文章

  1. PHP文件操作 之统计目录大小

    <?php //定义一个函数 统计目录大小函数 function dirSize($dirName) { //判断目录是否存在 if (!file_exists($dirName)) { die ...

  2. PHP遍历目录返回统计目录大小实例

    分享一个 PHP遍历目录并返回统计目录大小的方法.代码: <?php $dirname = "test1"; //mkdir($dirname); //遍历一层目录 func ...

  3. 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 ...

  4. php统计目录大小

    function dirSize($directroy) { $dir_size=0; $dir_handle = @opendir($directroy); if($dir_handle) { wh ...

  5. 使用php递归计算目录大小

    统计一个目录大小,因为不知道目录中子目录的深度,所以for循环很难实现,但是用递归调用很容易实现,只要统计出一个目录中所有文件的大小,那么每一次调用就可以了,随便建了个目录,建立一些文件,方法代码如下 ...

  6. PHP中统计目录中文件以及目录中目录的大小

    <?php  #循环遍历目录中所有的文件,并统计目录和文件的大小  $dirName="phpMyAdmin";  $dir=opendir($dirName);  #返回一 ...

  7. linux 系统统计目录下文件夹的大小

    du -ah --max-depth=1     这个是我想要的结果  a表示显示目录下所有的文件和文件夹(不含子目录),h表示以人类能看懂的方式,max-depth表示目录的深度. du命令用来查看 ...

  8. 一个统计目录文件大小的php函数

    早上刚到公司,头告诉我,抓紧写一个小函数,用来统计指定目录中文件大小,我了个去,动手吧,还好有点小基础,一会就完工了,哈哈.代码在下面咯. <? /** 统计目录文件大小的函数 @author  ...

  9. Linux系统下查看目录大小

    转载:http://blog.csdn.net/iamlaosong/article/details/7085178 我们有个系统每天要下载数据,为了检查下载数据是否正常,需要查看下载数据目录大小,因 ...

随机推荐

  1. Arduino-函数库和程序架构介绍

    (1)声明变量及接口的名称 (2)setup().在程序运行时首先要调用setup()函数[初始化函数],用于初始化变量.设置针脚的输出/输入类型.配置串口.引入类库文件等等.每次Arduino上电或 ...

  2. P3396 哈希冲突

    很好的根号算法(这种思想好像叫根号分治?) 首先,暴力是Ο(n2)的 考虑预处理: for(p=1;p<=n;p++) //枚举模数 ans[p][i%p]+=value[i]; 看似很好但还是 ...

  3. Codeforces Round #542 (Div. 1) 题解

    开学了住校了打不了深夜场 好难受啊QwQ A 显然对于每个起点,我们只需要贪心记录这个起点出发出去的糖果数量以及离自己最近的糖果 因为这个起点最后一次装载糖果一定是装载终点离自己最近的那个糖果 $ O ...

  4. POI操作excle

    将根目录下的poi-3.6-20091214.jar和Lib目录下三个通用包 commons-logging-1.1.jar junit-3.8.1.jar log4j-1.2.13.jar拷贝到项目 ...

  5. 基于范围的for循环(C++11)

    C++11新增了一种循环:基于范围的for循环.这简化了一种常见的循环任务:对数组(或容器类,如vector和array)的每个元素执行相同的操作,如下例所示 for语句允许简单的范围迭代:(只遍历, ...

  6. kettle使用记录

    1.linux系统抽取数据 export KETTLE_HOME=/home/oracle/Kettle/pdi-ce-6.1.0.1-196/data-integration export JAVA ...

  7. spring boot 业务场景简单,代码完整的demo们

    源码地址:https://github.com/zhzhair/spring-boot-examples.git 开发环境:windows,jdk8,spring boot2.1.4

  8. [mysql] 修复问题表Table '.xxxx' is marked as crashed and should be repaired

    程序执行的过程中,出现   Table '.xxxx' is marked as crashed and should be repaired 错误,上网查了一下,原来是表遭到损坏所致,具体修复办法如 ...

  9. 发送邮件工具类MailHelper

    using System; using System.Net; using System.Net.Mail; using System.Text; using System.Threading; na ...

  10. iOS unity 互相调用加载高德地图时

    需要增加 mapView.delegate = self 这是一种设计模式,有的人称为代理,有的人称为委托,比如有A,B两个控制器,由A可以push到B,B可以pop回A,现在有一种情况,A中有一个l ...