在向磁盘写入大量顺序数据时,我发现有一个内部4MB的缓冲区,并且在打开文件进行写入时,我指定了[FILE_FLAG_NO_BUFFERING][1]
,以便使用我的内部缓冲区。
但这也要求写入完整的扇区块(在我的机器上为512字节(。
我如何写最后一个N<512字节到磁盘?
WriteFile是否有允许这样做的标志?
我是否用额外的NUL
字符填充它们,然后将文件大小截断为正确的值?(使用SetFileValidData
或类似产品?(
对于那些想知道尝试这种方法的原因的人。我们的应用程序经常记录。为了处理这一问题,存在一个专用的日志线程,用于格式化日志并将其写入磁盘。此外,如果我们以最详细的信息进行日志记录,我们每秒的日志记录可能会超过磁盘系统的处理能力。(通常会注意到SAN系统没有经过很好调整的客户。(
因此,目标是尽可能多地写入日志,但也要注意我们何时开始过载系统,然后稍微推迟一点,比如减少日志的细节
因此,有一个想法是填充一个大的内存块,并将其提供给操作系统,希望减少开销。
正如注释所示,以这种方式编写文件可能不是现实情况下的最佳解决方案。但是,如果使用FILE_FLAG_NO_BUFFERING
进行写入,则
SetFileInformationByHandle是将文件标记为短于整个块的方法。
int data_len = len(str);
int len_last_block = BLOCKSIZE%datalen;
int padding_to_fill_block = (data_last_block == BLOCKSIZE ? 0 : (BLOCKSIZE-len_last_block);
str.append(' ', padding_to_fill_block);
ULONG bytes_written = 0;
::WriteFile(hFile, data, data_len+padding_to_fill_block, &bytes_written, NULL));
m_filesize += bytes_written;;
LARGE_INTEGER end_of_file_pos;
end_of_file_pos.QuadPart = m_filesize - padding_to_fill_block;
if (!::SetFileInformationByHandle(hFile, FileEndOfFileInfo, &end_of_file_pos, sizeof(end_of_file_pos)))
{
HRESULT hr = ::GetLastErrorMessage();
}