c - 如何使用 linux 原生 AIO 将数据写入不是 512*n 字节的偏移量?

标签 c linux aio

我正在编写一些像 Bittorrent 客户端这样的应用程序来从网上下载文件并将其写入本地文件。我将获取部分数据并写入文件。

例如,我将下载一个 1GB 的文件,我将得到 offset 100, data: 312 bytes, offset 1000000, data: 12345, offset 4000000 , 数据:888字节.

我正在使用 Linux 原生 AIO(io_setup, io_submit, io_getevents), 我找到了这个

When using linux kernel AIO, files are required to be opened in O_DIRECT mode. This introduces further requirements of all read and write operations to have their file offset, memory buffer and size be aligned to 512 bytes.

那么我怎样才能将数据写入一些不是 512 对齐的偏移量呢?

例如,首先我将 4 个字节写入一个文件,所以我必须这样做:

fd = open("a.txt", O_CREAT | O_RDWR | O_DIRECT, 0666);
struct iocb cb;
char data[512] = "asdf";
cb.aio_buf = ALIGN(data, 512);
cb.aio_offset = 512;
cb.aio_nbytes = 512;

然后我想在asdf之后追加数据:

struct iocb cb2;
char data2[512] = "ghij";
cb2.aio_buf = ALIGN(data2, 512);
cb2.aio_offset = 5;
cb2.aio_nbytes = 512;

写入会报错

Invalid argument (-22)

那么怎么做呢?

最佳答案

如果您不使用 O_DIRECT,您必须执行驱动程序会执行的操作。也就是说,读取整个 block ,更新你想要的部分,然后写回。 block 设备根本不允许较小的访问。

自己动手做效率会更高(比如,你可以以一次读写的代价更新同一个 block 中的多个断开连接的序列)。但是,由于您没有让驱动程序完成工作,因此您也无法在读取-修改-写入操作中获得任何原子性保证。

关于c - 如何使用 linux 原生 AIO 将数据写入不是 512*n 字节的偏移量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56266960/

相关文章:

c - 字符串在执行中途丢失数据 C

c - 使用赋值运算符的 If 子句的行为与使用等于运算符的行为相同

c - 如何编辑此函数调用以仅扫描数组的一半?

c++ - OS X 上的 AIO 与 Linux - 为什么它在 Mac OS X 10.6 上不起作用

c - 谁调用了C中的main函数

c - 为什么像clone()这样的系统调用会失败、恢复和暂停?

linux - Bash递归地替换名称上的许多空格

linux - 如何 grep 匹配具有多个选项的多个模式

linux - 为什么boost::aio基于epoll(synchronous)实现是异步的

linux - "Linux aio"和 "Linux native aio"是一回事吗?