windows 在写入文件之前预留磁盘空间以提高效率
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2356736/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reserve disk space before writing a file for efficiency
提问by haggag
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.
当我第一次启用日志记录时,我注意到我的一个项目中的一个巨大的性能下降。但是当达到日志文件限制并且程序再次开始写入文件的开头时,日志记录速度要快得多(大约快 50%)。将日志文件大小设置为数百 MB 是正常的。
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?
当我的程序第一次启动时,通过某个固定大小有效地保留磁盘空间的最佳方法是什么?
采纳答案by plinth
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
}
回答by Ali Lown
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.
wRAR 是正确的。使用您最喜欢的库打开一个新文件,然后查找倒数第二个字节并在那里写入 0。那应该分配所有需要的磁盘空间。
回答by Kari
If you are using C++ 17, you should do it with std::filesystem::resize_file
如果您使用的是C++ 17,则应该使用std::filesystem::resize_file
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.
像通过 POSIX 截断一样更改由 p 命名的常规文件的大小:如果文件大小以前大于 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
}
回答by Gabe
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);
}
回答by agile
You can use the SetFileValidDatafunction 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.
您可以使用SetFileValidData函数来扩展文件的逻辑长度,而不必将所有数据写出到磁盘。但是,因为它可以允许读取您可能没有特权的磁盘数据,所以它需要SE_MANAGE_VOLUME_NAME
特权才能使用。仔细阅读文档的备注部分。
Also implementation of SetFileValidDatadepend on fs driver. NTFS support it and FAT only since Win7.
SetFileValidData 的实现也依赖于 fs 驱动程序。NTFS 仅从 Win7 开始支持它和 FAT。