Home > Net >  How to get the true disk usage of a sparse file on windows?
How to get the true disk usage of a sparse file on windows?

Time:05-25

I am watching a book called "windows via c/c ". It says a programmer can create a sparse file with VirtualAlloc() on a FileMapping.

And I can see that this sparse file taking 1MB in file's properties in the book.
And the book say it only takes 64KB on disk actually .

So how can I get the actual size of a sparse file? Beside, I create a spare file with code as follow:

#include <iostream>
#include <Windows.h>
int main()
{
    using namespace std;
    HANDLE fileHandle = CreateFile(TEXT("D:\\sfile.txt"), GENERIC_READ | GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
    if(fileHandle==INVALID_HANDLE_VALUE)
    {
        cout << "INVALID FILE HANDLE" << endl;
        return 1;
    }
    HANDLE hFileMapping = CreateFileMapping(fileHandle, nullptr, PAGE_READWRITE|SEC_RESERVE, 0, 4*1024 * 1024, nullptr);
    if(hFileMapping==INVALID_HANDLE_VALUE||hFileMapping==NULL)
    {
        cout << "INVALID FILE MAPPING HANDLE" << endl;
        return 1;
    }
    PVOID view = MapViewOfFile(hFileMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 1024 * 1024);
    if(view == nullptr)
    {
        cout << "map failed" << endl;
        return 1;
    }
    PVOID revisePos = static_cast<PLONG_PTR>(view)   512;
    auto allocatePos =  (char*)VirtualAlloc(revisePos, 1024 * 1024, MEM_COMMIT, PAGE_READWRITE);
    char mess[] = "123456789 hello world!";
    strcpy_s(static_cast<char*>(revisePos), sizeof(mess), mess);
    UnmapViewOfFile(view);
    CloseHandle(hFileMapping);
    CloseHandle(fileHandle);

}

It will create 4MB file, although I just try to VirtualAlloc 1MB . It seems that this file actually take 4MB on windows by watching file's properties.
file's property
Why window's won't compress a sparse file? If windows won't compress it, when do I need a sparse file.

CodePudding user response:

You should check documentation rather than rely on the book.

You create a file mapping backed by the normal file with PAGE_READWRITE|SEC_RESERVE options.

File size is supposed to increase 4 MB to match size of mapping object:

If an application specifies a size for the file mapping object that is larger than the size of the actual named file on disk and if the page protection allows write access (that is, the flProtect parameter specifies PAGE_READWRITE or PAGE_EXECUTE_READWRITE), then the file on disk is increased to match the specified size of the file mapping object.

SEC_RESERVE has no effect at all:

This attribute has no effect for file mapping objects that are backed by executable image files or data files (the hfile parameter is a handle to a file).

  • Related