文件夹没有大小,文件夹只是文件的容器,文件的大小决定了文件夹大小。
要获得总体文件夹大小,您可以通过找到磁盘大小和可用空间然后减去这两个来得出文件夹大小的近似值。
在后台使用CIM_Directory和CIM_DataFile扫描文件夹。您可以使用管理范围和驱动器号 (D:) 调用扫描方法
我确实从一个 ThreadPool 线程中运行它,如下所示:
ManagementScope ManagementScope1 = new ManagementScope();
ManagementScope1.Connect();
ThreadPool.QueueUserWorkItem((que) => { scan(ManagementScope1, "D:"); });
使用 WMI 遍历文件夹
private void scan(ManagementScope scope, string drive)
{
var disk = scope.Device(drive).GetEnumerator();
if (!disk.MoveNext())
{
Add(String.Format("{0} drive not found",drive),0);
return;
}
Add(drive, disk.Current.Size() - disk.Current.FreeSpace());
// iterate over root Folders
foreach (var folder in scope.Folder(drive))
{
ulong totalsize = 0;
try
{
// iterate over the files
foreach (var file in scope.File(
drive,
folder.Path(),
folder.FileName()))
{
totalsize += file.FileSize();
}
// iterate over all subfolders
foreach (var subfolder in scope.SubFolder(drive
, folder.Path()
, folder.FileName()))
{
// iterate over files within a folder
foreach (var file in scope.File(
drive,
subfolder.Path(),
subfolder.FileName()))
{
totalsize += file.FileSize();
}
}
}
catch (Exception exp)
{
Debug.WriteLine(exp.Message);
}
Add(folder.Name(), totalsize);
}
}
扩展方法
原始代码变得接近不可维护,因此我实现了 ManagementScope 和 ManagementBaseObject 的扩展方法。
public static class ManagementObjectExtensions
{
const string WQL_DEVICE = "Select Size,FreeSpace from Win32_LogicalDisk where Deviceid='{0}'";
const string WQL_FOLDER = "Select Path, Filename, Name from CIM_Directory where Drive='{0}' and path='\\\\' and system = false and hidden = false and readable = true";
const string WQL_SUBFOLDER = "Select Path, Filename from CIM_Directory where Drive='{0}' and path like '{1}{2}\\\\%' and system = false and hidden = false and readable = true";
const string WQL_FILE = "Select FileSize from CIM_DataFile where Drive='{0}' AND Path = '{1}{2}\\\\' ";
// internal helper to get an enumerable collection from any WQL
private static ManagementObjectCollection GetWqlEnumerator(this ManagementScope scope, string wql, params object[] args)
{
return new ManagementObjectSearcher(
scope,
new ObjectQuery(
String.Format(wql, args)))
.Get();
}
public static ManagementObjectCollection Device(this ManagementScope scope, params object[] args)
{
return scope.GetWqlEnumerator(WQL_DEVICE, args);
}
public static ManagementObjectCollection Folder(this ManagementScope scope, params object[] args)
{
return scope.GetWqlEnumerator(WQL_FOLDER, args);
}
public static ManagementObjectCollection SubFolder(this ManagementScope scope, params object[] args)
{
return scope.GetWqlEnumerator(WQL_SUBFOLDER, args);
}
public static ManagementObjectCollection File(this ManagementScope scope, params object[] args)
{
return scope.GetWqlEnumerator(WQL_FILE, args);
}
public static string Path(this ManagementBaseObject mo)
{
return mo["Path"].ToString().Replace("\\","\\\\");
}
public static string Name(this ManagementBaseObject mo)
{
return mo["Name"].ToString();
}
public static string FileName(this ManagementBaseObject mo)
{
return mo["FileName"].ToString();
}
public static ulong FreeSpace(this ManagementBaseObject mo)
{
return (ulong)mo["FreeSpace"];
}
public static ulong Size(this ManagementBaseObject mo)
{
return (ulong) mo["Size"];
}
public static ulong FileSize(this ManagementBaseObject mo)
{
return (ulong) mo["FileSize"];
}
}
将项目添加到 Listview 的助手
如果需要,这个小助手会处理切换到 UI 线程
// UI Thread safe helper for adding an item
private void Add(string name, ulong size)
{
if (this.listView1.InvokeRequired)
{
this.listView1.Invoke(new MethodInvoker(() => Add(name, size)));
}
else
{
var lvi = new ListViewItem(name);
lvi.SubItems.Add(size.ToString());
this.listView1.Items.Add(lvi);
}
}
我在RRUZ的这个答案中查找了路径选择问题