NTFS 稀疏文件

稀疏文件(英语:sparse file)是一种计算机文件,它能尝试在文件内容大多为空时更有效率地使用文件系统的空间。它的原理是以简短的信息(元数据)表示空数据块,而不是在在磁盘上占用实际空间来存储空数据块。只有真实(非空)的数据块会按原样写入磁盘。

NTFS文件系统也支持稀疏文件,Windows也提供了一些API来处理稀疏文件。

首先是检查文件系统支持稀疏文件,通过GetVolumeInformation函数,判断lpFileSystemFlags参数返回的值是否包含FILE_SUPPORTS_SPARSE_FILES即可。通过C#进行P/Invoke调用代码如下:

public static bool IsSupportSparseFile(string path)
{
    var result = GetVolumeInformation(path, null, 0, out NullRef<DWORD>(), out NullRef<DWORD>(), out var fileSystemFlags, null, 0);
    if (result)
    {
        return (fileSystemFlags & FileSystemFlags.FILE_SUPPORTS_SPARSE_FILES) != 0;
    }
    else
    {
        throw new Win32Exception();
    }
}

接下来是将文件设置为稀疏文件,需要用到DeviceIoControl这一函数,然后配合FSCTL_SET_SPARSE。通过C#进行P/Invoke调用代码如下:

public static bool SetAsSparseFile(FileStream file, bool isSparseFile)
{
#if NET40 || NET45
    var size = Marshal.SizeOf(typeof(FILE_SET_SPARSE_BUFFER));
#else
    var size = Marshal.SizeOf<FILE_SET_SPARSE_BUFFER>();
#endif
    var FILE_SET_SPARSE_BUFFER = new FILE_SET_SPARSE_BUFFER
    {
        SetSparse = isSparseFile
        };

    var result = DeviceIoControl(file.SafeFileHandle.DangerousGetHandle(), FSCTL_SET_SPARSE, AsPointer(ref FILE_SET_SPARSE_BUFFER), size, NULL, 0, out _, NullRef<OVERLAPPED>());
    return result;
}

如果直接向文件写入0,文件不会保持稀疏性。需要用DeviceIoControl配合FSCTL_SET_ZERO_DATA才行。如果使用SetEndOfFile修改文件长度,文件会保持稀疏性。

更多关于稀疏文件的功能可以查看微软的文档

One thought on “NTFS 稀疏文件

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据