O_DIRECT模式下,使用pread64和pwrite64读写磁盘/文件

背景与目标

使用O_DIRECT模式打开文件,然后用pread64和pwrite64直接读写文件。由于磁盘本身也可以看做一个文件,因此open打开文件或者磁盘都是同样适用的。

注意事项

  1. 采用O_RDWR | O_DIRECT对文件进行打开,关键点在于O_DIRECT,表示不经过磁盘自带的缓存,直接对磁盘进行读写,在使用pread64和pwrite64时要求buffer的起始地址是4K对齐的,否则会失败,另外offset的偏移地址要求是512的整数倍,详细介绍可以看下面的参考资料。
  2. pread64和pwrite64的参数问题,主要是buffer的起始地址和offset,分别要求是4k对齐和512的整数倍。

源代码

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>

static const int kMemAlignSize = 4096;
static const int kDataSize = 1024;

int fd;

int open_file(const char *file) {
  fd = open(file, ç);
  if (fd < 0) {
    perror("open error!");
    return -1;
  }
  printf("fd open success!\n");
  return 0;
}

void close_file() {
  close(fd);
}

void test_write() {
  printf("-------------- write test --------------\n");
  char *buffer = nullptr;
  int code = posix_memalign((void **) &buffer, kMemAlignSize, kDataSize);
  assert(code == 0);

  strcpy(buffer, "hello,yongpu123");
  printf("buffer: %s\n", buffer);
  code = pwrite64(fd, buffer, kDataSize, 512);
  if (code != kDataSize) {
    printf("write failed %d\n", code);
  } else {
    printf("write success %d\n", code);
  }
  free(buffer);
}

void test_read() {
  printf("-------------- read test --------------\n");
  char *buffer = nullptr;
  int code = posix_memalign((void **) &buffer, kMemAlignSize, kDataSize);
  assert(code == 0);

  code = pread64(fd, buffer, kDataSize, 0);
  if (code != kDataSize) {
    printf("read failed %d\n", code);
  } else {
    printf("read success %d\n", code);
    printf("buffer: ");
    for(int i = 0 ; i < 1024; i++) {
      printf("%c", buffer[i]);
    }
  }
  free(buffer);
}

int main() {
  static const char *file= "vitual_disk";    // 普通文本文件
  //static const char *file= "/dev/sdq";     // 磁盘名

  int code = open_file(file);
  assert(code == 0);

  // test_write
  test_write();

  // test_read
  test_read();

  close_file();
  return 0;
}

运行结果:

使用vim打开vitaul_disk,结果如下:

说明数据写入和读出成功!

参考资料:glibc的 Asynchronous I/O 写性能测试_小屋-CSDN博客
测试主机是AIX6.1
 
测试数据是向文件中顺序写入 8K * 50000 大小的数据,生成的文件大约为390M
 
测试对比了两种写操作,一种是aio_write, 另一种是 pwrite64; dwFlags 是open文件时,传入的参数
 
第一种测试
 
dwFlags = O_RDWR |  O_LARGEFILE | O_DIRECT | O_CREAT | O_EXCL;
 
pw
https://blog.csdn.net/spche/article/details/5804413

linux open 函数O_DIRECT标志位使用说明_hhtang的专栏-CSDN博客打开文件的时候如果使用O_DIRECT按照man命令说的就是直接进行文件IO,而系统不进行缓存,会影响文件读写速度,但可能对用户内存影响较小。这个标志位在使用的时候还是有些东西需要注意的,否则写文件时既没有报错,而内容也没有写入文件,会搞得人一头雾水。注意事项:1. 每次写入的数https://blog.csdn.net/hhtang/article/details/6605951/

Linux的O_DIRECT选项(神文)_STN_LCD的专栏-CSDN博客http://laokaddk.blog.51cto.com/368606/699563/    在man 2 open的时候发现一个O_DIRECT选项,使用O_DIRECT选项后,可以不使用缓存直接写入。在海量数据写入的时候,不使用缓存貌似更快呢!于是也尝试写了一个用O_DIRECT选项的文件写入。完成O_DIRECT选项写入的代码还真不容易,使用new或者mahttps://blog.csdn.net/STN_LCD/article/details/66975464?utm_medium=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~default-4.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~default-4.no_search_link

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值