c++ - 如何使用直接io写入一个没有扩展文件大小的小文件
问题描述
如何使用直接 io 写入一个不更改文件大小的小文件。
假设我有一个文件,文件大小为 1.1KB,我使用直接 io 读取文件,并更改一些数据,然后写入文件......
见下文
//open file with O_DIRECT
handle_ = open("1.html", O_RDWR | O_DIRECT | O_SYNC | O_LARGEFILE,0777))
//file size is 1.1KB (i read 4KB)
pread64(handle_,buffer,4096,0);
memcpy(buffer,"11111",5);
//error (512b Aligned)
pwrite64(handle_,buffer,1.1KB,0);
//OK,but file size has been extended to 4KB
pwrite64(handle_,buffer,4KB,0);
这是一个现实世界的问题,因为某些软件也可能使用此文件,例如网络服务器,它会得到错误的文件大小并响应客户端更大的文件。
(必须是直接io,我有我的理由)
解决方案
如何使用直接io写入一个没有扩展文件大小的小文件
对不起,你不能——O_DIRECT
要求你做的 I/O 是 512 字节对齐的。假设KB
是 1024 字节,1.1 * 1024 = 1126.4
(这是一个奇怪的数字,因为它不是一个完整的字节)所以你必须将它四舍五入1536
才能使用,O_DIRECT
从而导致扩展。
您的选择仅限于:
- 执行
O_DIRECT
写入然后将文件截断为正确的大小(听起来这就是你最终要做的)。 - 使用仅写入文件的完整块倍数,
O_DIRECT
然后使用非写入写入最后一点O_DIRECT
。
如果这两个听起来都很糟糕,那么我只能将您指向@ted-lyngmo 的更多信息请求:
“必须是直接的 io,我有我的理由” - 愿意分享这些吗?
O_DIRECT
带有繁重的使用规则...
推荐阅读
- php - 银器验证器不适用于 silverstripe 的 CMS 前端
- sql - Postgres 无限自连接
- c - makefile 缺少分隔符,但这不是选项卡问题
- mongodb - 批量创建 - 发生错误时会发生什么
- c# - Entity Framework Core 中的动态 DbSet
- php - AJAX 不能输入表单中的所有值。插入查询
- sql - 从交叉连接中的最小行中选择其他属性
- javascript - 如何通过 Media Source Extension API 将视频和音频文件转换为流畅播放?
- node.js - 'setValue' 方法在 Angular 应用程序中不起作用
- vuejs2 - VueJS - 跳过观察者的第一个变化