获取文件夹所占空间的大小

时间:2021-10-10 12:30:38

虽然现在硬盘越来越大,但是清理垃圾还是必要的。这时我们往往需要一个获取文件夹所占空间大小的功能,从而判断垃圾文件的位置。

这个时候,我们常用的在右键属性中查看文件夹所占空间的方法显得效率实在太低。往往需要一些工具来辅助实现这个功能。一般有两个工具可以实现这个功能:diruse和du。diruse是MS在系统中的一个附加的工具,du是sysinternals公司的,不过sysinternals好像已经被MS收购了。这两个工具都是命令行工具,但也保持着MS一贯的简单易用的特点。

这里以diruse为例介绍其用法:

diruse /M /* c:\OTHER

Size (mb)  Files      Directory
2.91     14          SUB-TOTAL: C:\OTHER\BusinessInfo
61.98   1309        SUB-TOTAL: C:\OTHER\software
41.60     41         SUB-TOTAL: C:\OTHER\drivers
0.02     21          SUB-TOTAL: C:\OTHER\work
3.03      9          SUB-TOTAL: C:\OTHER\config
0.00      3          SUB-TOTAL: C:\OTHER\lnetwork
182.16    537        SUB-TOTAL: C:\OTHER\bkup
14.71      6          SUB-TOTAL: C:\OTHER\vpnclient
1.81     60          SUB-TOTAL: C:\OTHER\info
817.20    224        SUB-TOTAL: C:\OTHER\tools
515.25    449        SUB-TOTAL: C:\OTHER\wtnfiles
3089.50  10765       SUB-TOTAL: C:\OTHER\MP3
4730.18  13438       TOTAL

可以非常直观的看到各个文件夹所占的空间。

但是一个非常郁闷的地方是:这两个程序都不支持中文,一旦碰到中文文件夹就晕菜了,无法显示全部路径。作为MS的官方工具,有这个bug确实让人大跌眼镜。没办法,我只好写了个程序来纠正这个bug。 

获取文件夹所占空间的大小获取文件夹所占空间的大小代码
class  DirUseInfo
{
    
public   string  Path {  get private   set ; }
    
public   int  Percent {  get private   set ; }
    
public   int  FileCount {  get set ; }
    
public   long  Size {  get set ; }
            
    Lazy
< DirUseInfo[] >  subDirs;
    
public  DirUseInfo[] SubDirs {  get  {  return  subDirs.Value; } }

    
private  DirUseInfo( string  path,  long  size,  int  fileCount, int  percent)
    {
        
this .Path  =  path;
        
this .Size  =  size;
        
this .FileCount  =  fileCount;
        
this .Percent  =  percent;
        
this .subDirs  =  fileCount  ==   0   ?   new  Lazy < DirUseInfo[] > () :  new  Lazy < DirUseInfo[] > (()  =>  GetDirUseInfo(path));
    }

    
public   override   string  ToString()
    {
        
return   string .Format( " [{0}% {1} {2}] " , Percent, Size, Path);
    }

    
public   static  DirUseInfo[] GetDirUseInfo( string  dir)
    {
        var subDirs 
=  Directory.GetDirectories(dir);
        var p 
=  Process.Start( new  ProcessStartInfo( @"D:\Tools \Du\diruse.exe " @" /*  "   +  dir)
        {
            UseShellExecute 
=   false ,
            RedirectStandardOutput 
=   true ,
        });    
        p.WaitForExit();

        var output 
=  p.StandardOutput.ReadToEnd();
        var matches 
=  Regex.Matches(output,  @" (\d+|Access Denied)\s+(\d+).+ " );

        
if (subDirs.Length != matches.Count - 1 )     // match最后一项是汇总
             throw   new  InvalidOperationException();

        var totalSize 
=   long .Parse(matches[matches.Count  -   1 ].Groups[ 1 ].Value);

        var dirsUseInfo 
=   new  DirUseInfo[subDirs.Length];
        
for  ( int  i  =   0 ; i  <  dirsUseInfo.Length; i ++ )
        {
            var groups 
=  matches[i].Groups;
            var path 
=  subDirs[i];
            var fileCount 
=   int .Parse(groups[ 2 ].Value);
            var size 
=  matches[i].Value.StartsWith( " Access Denied " ?   0  :  long .Parse(groups[ 1 ].Value);
            var percent 
=  ( int )(size  *   100   /  totalSize);

            dirsUseInfo[i] 
=   new  DirUseInfo(path, size, fileCount, percent);
        }

        
return  dirsUseInfo;
    }
}

 

原理很简单,仅仅是用C#把diruse的输出封装和匹配了一下,使其生成一个DirUseInfo的对象,利用diruse的输出获取了一些常用的信息。从而可以集成到windows程界面的程序中去。我自己用的时候是用wpf写了一个界面的,不过还不是很令人满意,就不献丑了。这里就仅仅提供一下diruse的封装,以供有同样需求的朋友参考。