背景与目标
使用O_DIRECT模式打开文件,然后用pread64和pwrite64直接读写文件。由于磁盘本身也可以看做一个文件,因此open打开文件或者磁盘都是同样适用的。
注意事项
- 采用O_RDWR | O_DIRECT对文件进行打开,关键点在于O_DIRECT,表示不经过磁盘自带的缓存,直接对磁盘进行读写,在使用pread64和pwrite64时要求buffer的起始地址是4K对齐的,否则会失败,另外offset的偏移地址要求是512的整数倍,详细介绍可以看下面的参考资料。
- 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,结果如下:
说明数据写入和读出成功!