虽然现在硬盘越来越大,但是清理垃圾还是必要的。这时我们往往需要一个获取文件夹所占空间大小的功能,从而判断垃圾文件的位置。
这个时候,我们常用的在右键属性中查看文件夹所占空间的方法显得效率实在太低。往往需要一些工具来辅助实现这个功能。一般有两个工具可以实现这个功能: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。
{
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的封装,以供有同样需求的朋友参考。