Reserve disk space before writing a file for effic

2020-02-08 15:54发布

I have noticed a huge performance hit in one of my projects when logging is enabled for the first time. But when the log file limit is reached and the program starts writing to the beginning of the file again, the logging speed is much faster (about 50% faster). It's normal to set the log file size to hundreds of MBs.

Most download managers allocate dummy file with the required size before starting to download the file. This makes the writing more effecient because the whole chunk is allocated at once.

What is the best way to reserve disk space efficiently, by some fixed size, when my program starts for the first time?

标签: windows
5条回答
爷的心禁止访问
2楼-- · 2020-02-08 16:06
void ReserveSpace(LONG spaceLow, LONG spaceHigh, HANDLE hFile)
{
    DWORD err = ::SetFilePointer(hFile, spaceLow, &spaceHigh, FILE_BEGIN);

    if (err == INVALID_SET_FILE_POINTER) {
        err = GetLastError();
        // handle error
    }
    if (!::SetEndOfFile(hFile)) {
        err = GetLastError();
        // handle error
    }
    err = ::SetFilePointer(hFile, 0, 0, FILE_BEGIN); // reset
}
查看更多
做自己的国王
3楼-- · 2020-02-08 16:06

wRAR is correct. Open a new file using your favourite library, then seek to the penultimate byte and write a 0 there. That should allocate all the required disk space.

查看更多
Melony?
4楼-- · 2020-02-08 16:12

You can use the SetFileValidData function to extend the logical length of a file without having to write out all that data to disk. However, because it can allow to read disk data to which you may not otherwise have been privileged, it requires the SE_MANAGE_VOLUME_NAME privilege to use. Carefully read the Remarks section of the documentation.

Also implementation of SetFileValidData depend on fs driver. NTFS support it and FAT only since Win7.

查看更多
时光不老,我们不散
5楼-- · 2020-02-08 16:23

Here's a simple function that will work for files of any size:

void SetFileSize(HANDLE hFile, LARGE_INTEGER size)
{
    SetFilePointer(hFile, size, NULL, FILE_BEGIN);
    SetEndOfFile(hFile);
}
查看更多
爷、活的狠高调
6楼-- · 2020-02-08 16:32

If you are using C++ 17, you should do it with std::filesystem::resize_file

Link

Changes the size of the regular file named by p as if by POSIX truncate: if the file size was previously larger than new_size, the remainder of the file is discarded. If the file was previously smaller than new_size, the file size is increased and the new area appears as if zero-filled.

#include <iostream>
#include <iomanip>
#include <fstream>
#include <filesystem>

namespace fs = std::filesystem;

int main()
{
    fs::path p = fs::current_path() / "example.bin"; 
    std::ofstream(p).put('a');
    fs::resize_file(p, 1024*1024*1024); // resize to 1 G
}
查看更多
登录 后发表回答