博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
实现 du 命令
阅读量:4049 次
发布时间:2019-05-25

本文共 2398 字,大约阅读时间需要 7 分钟。

 

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

du命令用来查看目录或文件所占用磁盘空间的大小。常用选项组合为:du -sh

  一、du的功能:`du` reports the amount of disk space used by the specified files and for each subdirectory (of directory arguments). with no arguments,`du` reports the disk space for the current directory。

  很明显,与df不同,它用来查看文件或目录所占用的磁盘空间的大小。

  二、du常用的选项:

  -h:以人类可读的方式显示

  -a:显示目录占用的磁盘空间大小,还要显示其下目录和文件占用磁盘空间的大小

  -s:显示目录占用的磁盘空间大小,不要显示其下子目录和文件占用的磁盘空间大小

  -c:显示几个目录或文件占用的磁盘空间大小,还要统计它们的总和

  --apparent-size:显示目录或文件自身的大小

  -l :统计硬链接占用磁盘空间的大小

  -L:统计符号链接所指向的文件占用的磁盘空间大小

  一、du -h:这个就不多说了。

  二、du -a:使用此选项时,显示目录和目录下子目录和文件占用磁盘空间的大小。

 

 

 

 

 

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)
}
 

 

 

 

参考摘录:

 

 

转载地址:http://tzcci.baihongyu.com/

你可能感兴趣的文章
Java中数字转大写货币(支持到千亿)
查看>>
Java.nio
查看>>
函数模版类模版和偏特化泛化的总结
查看>>
VMware Workstation Pro虚拟机不可用解决方法
查看>>
最简单的使用redis自带程序实现c程序远程访问redis服务
查看>>
redis学习总结-- 内部数据 字符串 链表 字典 跳跃表
查看>>
iOS 对象序列化与反序列化
查看>>
iOS 序列化与反序列化(runtime) 01
查看>>
iOS AFN 3.0版本前后区别 01
查看>>
iOS ASI和AFN有什么区别
查看>>
iOS QQ侧滑菜单(高仿)
查看>>
iOS 扫一扫功能开发
查看>>
iOS app之间的跳转以及传参数
查看>>
iOS __block和__weak的区别
查看>>
Android(三)数据存储之XML解析技术
查看>>
Spring JTA应用之JOTM配置
查看>>
spring JdbcTemplate 的若干问题
查看>>
Servlet和JSP的线程安全问题
查看>>
GBK编码下jQuery Ajax中文乱码终极暴力解决方案
查看>>
Oracle 物化视图
查看>>