在写入文件之前保留磁盘空间以提高效率

时间:2010-03-01 15:15:13

标签: windows

首次启用日志记录时,我注意到我的一个项目中出现了巨大的性能损失。但是当达到日志文件限制并且程序再次开始写入文件的开头时,日志记录速度要快得多(大约快50%)。将日志文件大小设置为数百MB是正常的。

大多数下载管理器在开始下载文件之前分配具有所需大小的虚拟文件。这使得写作更有效,因为整个块一次分配。

当我的程序第一次启动时,以某种固定大小有效保留磁盘空间的最佳方法是什么?

6 个答案:

答案 0 :(得分:8)

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
}

答案 1 :(得分:4)

wRAR是正确的。 使用您喜欢的库打开一个新文件,然后寻找倒数第二个字节并在那里写一个0。那应该分配所有必需的磁盘空间。

答案 2 :(得分:0)

这是一个适用于任何大小文件的简单函数:

void SetFileSize(HANDLE hFile, LARGE_INTEGER size)
{
    SetFilePointer(hFile, size, NULL, FILE_BEGIN);
    SetEndOfFile(hFile);
}

答案 3 :(得分:0)

您可以使用SetFileValidData函数扩展文件的逻辑长度,而无需将所有数据写入磁盘。但是,因为它可以允许读取您可能没有特权的磁盘数据,所以它需要SE_MANAGE_VOLUME_NAME权限才能使用。请仔细阅读文档的备注部分。

SetFileValidData的实现也取决于fs驱动程序。 自Win7以来,NTFS仅支持它和FAT。

答案 4 :(得分:0)

如果您使用的是 C ++ 17 ,则应使用std::filesystem::resize_file

Link

  

更改由p命名的常规文件的大小,就像通过POSIX truncate进行更改一样:如果文件大小以前大于new_size,则将丢弃文件的其余部分。如果文件以前小于new_size,则文件大小会增加,并且新区域会显示为零填充。

#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
}

答案 5 :(得分:0)

如果您使用的是C#,则可以在SetLength上调用FileStream,以立即为文件设置初始大小。

例如

using (var fileStream = File.Open(@"file.txt", FileMode.Create, FileAccess.Write, FileShare.Read))
{
    fileStream.SetLength(1024 * 1024 * 1024); // Reserve 1 GB
}
相关问题