How to create a sparse file on NTFS?

前端 未结 2 1390
独厮守ぢ
独厮守ぢ 2021-01-04 07:13

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,
        F         


        
相关标签:
2条回答
  • 2021-01-04 07:47
    #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;
    }
    
    0 讨论(0)
  • 2021-01-04 08:04

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

    0 讨论(0)
提交回复
热议问题