如何在 NTFS 上创建稀疏文件?

发布于 2024-09-29 15:01:56 字数 651 浏览 4 评论 0原文

我正在测试一个稀疏文件。 但我的测试代码不能很好地工作。

HANDLE h = CreateFileW(L"D:\\sparse.test",
        GENERIC_READ|GENERIC_WRITE,
        FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
        0,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SPARSE_FILE,
        0);

DWORD d = GetFileAttributes(L"D:\\sparse.test");
// The function returns 32(FILE_ATTRIBUTE_ARCHIVE).
// Where is FILE_ATTRIBUTE_SPARSE_FILE flag?
// How do I make a sparse file.

DWORD written;
WriteFile(h, "aaa", 3, &written, 0);
SetFilePointer(h, 2*1024*1024*1023, 0, FILE_BEGIN);
SetEndOfFile(h);
WriteFile(h, "bbb", 3, &written, 0);

I'm testing a sparse file.
But my test code doesn't work well.

HANDLE h = CreateFileW(L"D:\\sparse.test",
        GENERIC_READ|GENERIC_WRITE,
        FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
        0,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SPARSE_FILE,
        0);

DWORD d = GetFileAttributes(L"D:\\sparse.test");
// The function returns 32(FILE_ATTRIBUTE_ARCHIVE).
// Where is FILE_ATTRIBUTE_SPARSE_FILE flag?
// How do I make a sparse file.

DWORD written;
WriteFile(h, "aaa", 3, &written, 0);
SetFilePointer(h, 2*1024*1024*1023, 0, FILE_BEGIN);
SetEndOfFile(h);
WriteFile(h, "bbb", 3, &written, 0);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

猥︴琐丶欲为 2024-10-06 15:01:56
#include <windows.h>
#include <string>
#include <iostream>

HANDLE CreateSparseFile(LPCTSTR lpSparseFileName)
{
    // Use CreateFile as you would normally - Create file with whatever flags 
    //and File Share attributes that works for you
    DWORD dwTemp;

    HANDLE hSparseFile = CreateFile(lpSparseFileName,
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    if (hSparseFile == INVALID_HANDLE_VALUE)
        return hSparseFile;

    DeviceIoControl(hSparseFile,
        FSCTL_SET_SPARSE,
        NULL,
        0,
        NULL,
        0,
        &dwTemp,
        NULL);
    return hSparseFile;
}

DWORD SetSparseRange(HANDLE hSparseFile, LONGLONG start, LONGLONG size)
{
    // Specify the starting and the ending address (not the size) of the 
    // sparse zero block
    FILE_ZERO_DATA_INFORMATION fzdi;
    fzdi.FileOffset.QuadPart = start;
    fzdi.BeyondFinalZero.QuadPart = start + size;
    // Mark the range as sparse zero block
    DWORD dwTemp;
    SetLastError(0);
    BOOL bStatus = DeviceIoControl(hSparseFile,
        FSCTL_SET_ZERO_DATA,
        &fzdi,
        sizeof(fzdi),
        NULL,
        0,
        &dwTemp,
        NULL);
    if (bStatus) return 0; //Sucess
    else {
        DWORD e = GetLastError();
        return(e); //return the error value
    }
}
int _tmain(int argc, _TCHAR* argv[])
{
    if (argc < 3) {
        std::cerr << "USAGE: SparseFile filename size" << std::endl;
        return 1;
    }

    try {
        ULONGLONG size = std::stoull(argv[2]);
        HANDLE h = CreateSparseFile(argv[1]);
        if (h == INVALID_HANDLE_VALUE) {
            std::cerr << "Unable to create file" << std::endl;
            return 1;
        }
        if (SetSparseRange(h, 0, size) != 0) {
            std::cerr << "Unable to set sparse range" << std::endl;
            return 1;
        }
        LARGE_INTEGER seek;
        seek.QuadPart = size;
        if (!SetFilePointerEx(h, seek, 0, 0)) {
            std::cerr << "Unable to seek to desired offset" << std::endl;
            return 1;
        }
        SetEndOfFile(h);
        CloseHandle(h);
    } catch (const std::exception &ex) {
        std::cerr << ex.what() << std::endl;
    }

    return 0;
}
#include <windows.h>
#include <string>
#include <iostream>

HANDLE CreateSparseFile(LPCTSTR lpSparseFileName)
{
    // Use CreateFile as you would normally - Create file with whatever flags 
    //and File Share attributes that works for you
    DWORD dwTemp;

    HANDLE hSparseFile = CreateFile(lpSparseFileName,
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    if (hSparseFile == INVALID_HANDLE_VALUE)
        return hSparseFile;

    DeviceIoControl(hSparseFile,
        FSCTL_SET_SPARSE,
        NULL,
        0,
        NULL,
        0,
        &dwTemp,
        NULL);
    return hSparseFile;
}

DWORD SetSparseRange(HANDLE hSparseFile, LONGLONG start, LONGLONG size)
{
    // Specify the starting and the ending address (not the size) of the 
    // sparse zero block
    FILE_ZERO_DATA_INFORMATION fzdi;
    fzdi.FileOffset.QuadPart = start;
    fzdi.BeyondFinalZero.QuadPart = start + size;
    // Mark the range as sparse zero block
    DWORD dwTemp;
    SetLastError(0);
    BOOL bStatus = DeviceIoControl(hSparseFile,
        FSCTL_SET_ZERO_DATA,
        &fzdi,
        sizeof(fzdi),
        NULL,
        0,
        &dwTemp,
        NULL);
    if (bStatus) return 0; //Sucess
    else {
        DWORD e = GetLastError();
        return(e); //return the error value
    }
}
int _tmain(int argc, _TCHAR* argv[])
{
    if (argc < 3) {
        std::cerr << "USAGE: SparseFile filename size" << std::endl;
        return 1;
    }

    try {
        ULONGLONG size = std::stoull(argv[2]);
        HANDLE h = CreateSparseFile(argv[1]);
        if (h == INVALID_HANDLE_VALUE) {
            std::cerr << "Unable to create file" << std::endl;
            return 1;
        }
        if (SetSparseRange(h, 0, size) != 0) {
            std::cerr << "Unable to set sparse range" << std::endl;
            return 1;
        }
        LARGE_INTEGER seek;
        seek.QuadPart = size;
        if (!SetFilePointerEx(h, seek, 0, 0)) {
            std::cerr << "Unable to seek to desired offset" << std::endl;
            return 1;
        }
        SetEndOfFile(h);
        CloseHandle(h);
    } catch (const std::exception &ex) {
        std::cerr << ex.what() << std::endl;
    }

    return 0;
}
毁虫ゝ 2024-10-06 15:01:56

您必须创建一个普通文件,然后使用 DeviceIoControl FSCTL_SET_SPARSE 到使其成为稀疏文件。

You have to create a normal file, then use DeviceIoControl with FSCTL_SET_SPARSE to make it a sparse file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文