winapi - 将最后 N 个字节写入使用 FILE_FLAG_NO_BUFFERING 打开的文件
问题描述
在将大量顺序数据写入磁盘时,我发现有一个内部 4MB 缓冲区,并且在打开文件进行写入时我指定了[FILE_FLAG_NO_BUFFERING][1]
,以便使用我的内部缓冲区。
但这也产生了写入完整扇区块(我的机器上为 512 字节)的要求。
如何将最后 N<512 个字节写入磁盘?
WriteFile 是否有一些标志允许这样做?
我是否用额外的NUL
字符填充它们,然后将文件大小截断到正确的值?(有SetFileValidData
还是类似的?)
对于那些想知道尝试这种方法的原因的人。我们的应用程序记录了很多。为了处理这个问题,存在一个专门的日志线程,它可以格式化日志并将其写入磁盘。此外,如果我们以最完整的细节记录,我们每秒记录的数据可能会超出磁盘系统的处理能力。(对于 SAN 系统调整不佳的客户,通常会注意到这一点。)
因此,目标是尽可能多地写入日志,但也要注意我们何时开始使系统超载,然后稍作保留,例如减少日志的详细信息。
因此,有一个想法是填充一个大内存块并将其提供给操作系统,希望减少开销。
解决方案
正如评论所暗示的那样,以这种方式编写文件可能不是现实世界情况的最佳解决方案。但是如果FILE_FLAG_NO_BUFFERING
使用 write with,
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('\0', 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();
}
推荐阅读
- reactjs - 没有在反应中调度路由上的动作
- sql - 字符串操作/正则表达式
- python - 将 json 与顶级数组配对
- python - 我在 AWS 上有一个 API,如何使用 django 发布 json 数据?
- bash - bash 脚本:在非文件检查中使用 -e
- r - 将 csv 文件移动到存档中的特定命名文件夹
- android - 每次推送到 Play 商店内部发布轨道后获取未知用户注册
- python - 使用 Python 在 Mac 上自动化 Outlook
- javascript - Gmail API:在没有用户交互的情况下应用身份验证令牌时出现问题
- javascript - 表单验证失败后如何显示tippy.js工具提示