2018 06 26 22 08 [winapi] 在NTFS下建立壓縮檔案

這裡所謂的壓縮檔案,並不是指zip這種壓縮檔,
而是在檔案系統上,壓縮內容的檔案,
也就是可以節省實際使用的硬碟空間.
等同在檔案管理員,選檔案內容->進階->壓縮內容,節省磁碟空間.
以下就是範例,
要注意一點是,所開啟的檔案需要有讀寫的權限.
要不然 FSCTL_SET_COMPRESSION 的 DeviceIoControl 會失敗,
所以這邊是用 GENERIC_WRITE | GENERIC_READ .

update: 在windows 7 下, DeviceIoControl 的 lpBytesReturned 不能為NULL.


#include <windows.h>
#include <stdio.h>

int main()
{
    HANDLE hLog;
    DWORD written;
    BOOL b;
    int i;
    USHORT type = COMPRESSION_FORMAT_LZNT1;
    hLog = (HANDLE)CreateFileW(L"C:\\logs\\test.csv", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, NULL);

    b = DeviceIoControl((HANDLE)hLog,              // handle to file or directory
        FSCTL_SET_COMPRESSION,         // dwIoControlCode
        (LPVOID)&type,           // input buffer
        (DWORD)sizeof(type),         // size of input buffer
        NULL,                          // lpOutBuffer
        0,                             // nOutBufferSize
        (LPDWORD)&written,     // number of bytes returned
        (LPOVERLAPPED)NULL); // OVERLAPPED structure
    printf("b=%d\n", b);

    for (i = 0; i < 1000; i++) {
        b = WriteFile(hLog, L"1234567890", 20, &written, NULL);
        printf("b=%d\n", b);
    }
    CloseHandle(hLog);

    return 0;
}