在 Windows 上,以下在 C# 中效果很好(至少要获得最常用的尺寸):
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern bool GetDiskFreeSpaceEx(string lpDirectoryName, out ulong lpFreeBytesAvailable, out ulong lpTotalNumberOfBytes, out ulong lpTotalNumberOfFreeBytes);
这是一些示例代码(实际上并没有以这种形式编译,而是分散在多个文件中的工作代码的点点滴滴):
/// <summary>
/// A compilation of the properties of folders and files in a file system.
/// </summary>
public struct FileSystemProperties
{
private FileSystemProperties(long? totalBytes, long? freeBytes, long? availableBytes)
: this()
{
TotalBytes = totalBytes;
FreeBytes = freeBytes;
AvailableBytes = availableBytes;
}
/// <summary>
/// Gets the total number of bytes on the drive.
/// </summary>
public long? TotalBytes { get; private set; }
/// <summary>
/// Gets the number of bytes free on the drive.
/// </summary>
public long? FreeBytes { get; private set; }
/// <summary>
/// Gets the number of bytes available on the drive (counts disk quotas).
/// </summary>
public long? AvailableBytes { get; private set; }
/// <summary>
/// Gets the properties for this file system.
/// </summary>
/// <param name="volumeIdentifier">The path whose volume properties are to be queried.</param>
/// <param name="cancel">An optional <see cref="CancellationToken"/> that can be used to cancel the operation.</param>
/// <returns>A <see cref="FileSystemProperties"/> containing the properties for the specified file system.</returns>
public static FileSystemProperties GetProperties(string volumeIdentifier)
{
ulong available;
ulong total;
ulong free;
if (GetDiskFreeSpaceEx(volumeIdentifier, out available, out total, out free))
{
return new FileSystemProperties((long)total, (long)free, (long)available);
}
return new FileSystemProperties(null, null, null);
}
/// <summary>
/// Asynchronously gets the properties for this file system.
/// </summary>
/// <param name="volumeIdentifier">The path whose volume properties are to be queried.</param>
/// <param name="cancel">An optional <see cref="CancellationToken"/> that can be used to cancel the operation.</param>
/// <returns>A <see cref="Task"/> containing the <see cref="FileSystemProperties"/> for this entry.</returns>
public static async Task<FileSystemProperties> GetPropertiesAsync(string volumeIdentifier, CancellationToken cancel = default(CancellationToken))
{
return await Task.Run(() =>
{
ulong available;
ulong total;
ulong free;
if (GetDiskFreeSpaceEx(volumeIdentifier, out available, out total, out free))
{
return new FileSystemProperties((long)total, (long)free, (long)available);
}
return new FileSystemProperties(null, null, null);
}, cancel);
}
}
不要试图在 Linux 或 Mac 上使用它——它必须为那些重写(我很想看看)。