首页 > 解决方案 > 为什么没有写入直接 I/O 文件?

问题描述

我试图理解直接 I/O。为此,我编写了这个小玩具代码,它只是应该打开一个文件并向其写入一个文本字符串:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>


int main(int argc, char **argv) {

  char thefile[64];
  int fd;
  char message[64]="jsfreowivanlsaskajght";
  sprintf(thefile, "diotestfile.dat");
  if ((fd = open(thefile,O_DIRECT | O_RDWR | O_CREAT, S_IRWXU)) == -1) {
          printf("error opening file\n");
          exit(1);
  }
  write(fd, message, 64);
  close(fd);

}

我对 Cray 和 GNU 的编译命令是

cc -D'_GNU_SOURCE' diotest.c

对于英特尔来说

cc -D'_GNU_SOURCE' -xAVX diotest.c

在所有三个编译器下,文件 diotestfile.dat 都是以正确的权限创建的,但从未向其中写入任何数据。可执行文件完成后,输出文件为空白。这O_DIRECT是罪魁祸首(或者,更准确地说,我猜是我对 的错误处理O_DIRECT)。如果我把它拿出来,代码就可以正常工作。我在尝试使用的更复杂的代码中看到了同样的问题。我需要做些什么不同的事情?

标签: cfileio

解决方案


继续 Ian Abbot 的评论,我发现可以通过向“消息”数组添加对齐属性来解决问题:

#define BLOCK_SIZE 4096
int bytes_to_write, block_size=BLOCK_SIZE;
bytes_to_write = ((MSG_SIZE + block_size - 1)/block_size)*block_size;
char message[bytes_to_write]  __attribute__ ((aligned(BLOCK_SIZE)));

(系统 I/O 块大小为 4096。)

所以解决了它。仍然不能声称了解正在发生的一切。如果您愿意,请随时启发我。感谢大家的评论。


推荐阅读