有时候,读写文件并不想要使用系统缓存(page cache),此时 direct 文件读写就派上了用场,使用方法:

(1)打开文件时,添加O_DIRECT参数:

需要定义_GNU_SOURCE,否则找不到O_DIRECT宏定义

示例片段:

#define _GNU_SOURCE

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> int fd = open("test.out", O_RDWR | O_CREAT | O_DIRECT, );

(2)读写操作的传输数据大小和缓冲区地址都需要按照一定的规则对齐:

Linux下,对于不同的文件系统和内核版本,需要的对齐边界不同,也没有统一的接口可以获取到该边界值。

对于kernel 2.4版本:传输大小和缓冲区地址均需要按照访问文件系统的逻辑块大小对齐,比如文件系统的块大小是4K,buffer地址需要按照4K对齐,需要读写4K倍数的数据

对于kernel 2.6版本:传输大小和缓冲区地址按照目标存储设备的扇区大小(一般512)对齐

可使用memalign (malloc.h)来分配指定地址对齐的资源接口:void *memalign(size_t boundary, size_t size);

完整示例程序:

#define _GNU_SOURCE

#include <sys/types.h>
#include <fcntl.h>
#include <malloc.h>
#include <stdio.h>
#include <errno.h>
#include <string.h> int main(void) {
char hello_str[] = "Hello World!";
void *write_buffer;
void *read_buffer;
int fd;
int ret = ; fd = open("test.out", O_RDWR | O_CREAT | O_DIRECT, );
if (fd < ) {
printf("Failed to open file\n");
return fd;
} /* allocate a 1024 bytes buffer */
write_buffer = memalign(, * ); // align by 512
if (!write_buffer) {
printf("Failed to alloc write buffer\n");
ret = -ENOMEM;
goto bad_write_buffer;
} memcpy(write_buffer, hello_str, sizeof(hello_str)); ret = write(fd, write_buffer, * );
if (ret < ) {
printf("Failed to write file\n");
goto bad_write;
} lseek(fd, , SEEK_SET); // read previous write data read_buffer = memalign(, * );
if (!read_buffer) {
printf("Failed to alloc read buffer\n");
ret = -ENOMEM;
goto bad_read_buffer;
} ret = read(fd, read_buffer, * );
if (ret <) {
printf("Failed to read file\n");
goto bad_read;
} printf("read from file : %s\n", read_buffer); bad_read:
free(read_buffer);
bad_read_buffer:
bad_write:
free(write_buffer);
bad_write_buffer:
close(fd);
return ret;
}

引用Linus的话:

"The thing that has always disturbed me about O_DIRECT is that the whole interface is just stupid, and was probably designed by a deranged monkey on some serious mind-controlling substances."—Linus(O_DIRECT就是一坨屎)

PS:

O_DIRECT的详细描述,可以看linux open系统调用的文档:http://man7.org/linux/man-pages/man2/open.2.html

Linux Direct 文件读写(文件DIO)的更多相关文章

  1. 【转】 Linux内核中读写文件数据的方法--不错

    原文网址:http://blog.csdn.net/tommy_wxie/article/details/8193954 Linux内核中读写文件数据的方法  有时候需要在Linuxkernel--大 ...

  2. Android 怎样在linux kernel 中读写文件

    前言          欢迎大家我分享和推荐好用的代码段~~ 声明          欢迎转载,但请保留文章原始出处:          CSDN:http://www.csdn.net        ...

  3. 【转】在linux内核中读写文件 -- 不错

    原文网址:http://blog.csdn.net/tommy_wxie/article/details/8194276 1. 序曲 在用户态,读写文件可以通过read和write这两个系统调用来完成 ...

  4. python文件读写 文件修改

    #设置一个变量f为文件对象,并打开文件#写文件#f = open('user.txt','w',encoding='utf-8') #f是一个文件对象f=open(r'c:\Users\PL\Desk ...

  5. Python 文件读写 文件和路径

    1.在Windows上,使用倒斜杆作为文件夹之间的分隔符,在Linux上,使用正斜杠作为路径分隔符.在编写Python脚本时,可以os.path.join()函数来处理 在Windows环境下命令如下 ...

  6. Python文件读写 - 文件r+ a+ open读写实际表现[示例]

    先说结论: 文件r+ open: 1. write()不能实现插入写,它总是覆盖写或附加写: 2. 如果文件一打开即write(),则从开头覆盖写; 3. 如果文件一打开,用f.seek()指定文件指 ...

  7. LINUX读写文件

    body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...

  8. Lua读写文件

    文件读写 文件读写对制作游戏很有帮助.可以调用别的文件中的代码,保存最高分.游戏存档.玩家状态等信写到文件中. 首先,让我们看一个简单的命令:dofile.这个命令会读入另一个文件的代码并立即执行. ...

  9. 处理Python2.7读写文件中的中文乱码问题

    1.设置默认编码 在Python代码中的任何地方出现中文,编译时都会报错,这时可以在代码的首行添加相应说明,明确utf-8编码格式,可以解决一般情况下的中文报错.当然,编程中遇到具体问题还需具体分析啦 ...

  10. C++中文件读写的操作

    在C++中读读写文件一般指的就是磁盘中的文本文件和二进制文件: 文本文件:以字符序列组成的文件 二进制文件:由二进制组成的文件 读写文件采用ofstream和ifstream文件流,两者可用头文件&l ...

随机推荐

  1. 快速同步GitHub代码库

    因伟大的墙的存在,github下载速度奇慢, 简单办法,在csdn code建一个账号,然后创建工程的时候选择导入模式, 填入github的项目git URL. 然后.. 从csdn的code下载就快 ...

  2. BC之The mook jong

    Problem Description ZJiaQ want to become a strong man, so he decided to play the mook jong.ZJiaQ wan ...

  3. 蓝桥杯---汉字取首字母(位运算 & 水题)

    确实题目虽然有点水,但是开始的时候好像还真的没有想到怎么提取出这个编号一不小心感觉可以可以用unsigned char 这种类型,直接转为16进制,但是之后发现虽然第一次在codeblock中还行,但 ...

  4. (转) C# textbox 限制输入问题

    原理:e.handled代表这次按键动作是否交由用户自己处理,如果为true代表由用户处理,系统不再过问,这里的应用是拦截,即通知系统我要处理这个数据,但又不处理(丢弃数据),从而实现拦截的效果. 在 ...

  5. php文件删除unlink()详解

    请记住从PHP文件创建的教训,我们创建了一个文件,名为testFile.txt . $myFile = "testFile.txt"; $fh = fopen($myFile, ' ...

  6. JavaScript对象的创建之使用json格式定义

    json: javascript simple object notation. json就是js的对象,但是它省去了xml中的标签,而是通过{}来完成对象的说明. 定义对象 var person = ...

  7. 初探appium之appium的使用

    上一篇中已经讲了python+appium的环境搭建.这里简单的讲一下appium的使用. 我也是第一次使用appium,看了教程问了人.知道appium可以通过模拟也可以连接上手机使用.本篇中,先使 ...

  8. pytest学习笔记(二)

    继续文档的第二章 (一)pytest中可以在命令行中静态/动态添加option,这里没什么好讲的,略过... 这里面主要讲下如何试用skip/xfail,还有incremental(包含一些列的测试步 ...

  9. selenium 速查手册 python版

    1.安装与配置 pip install selenium 基本使用selenium都是为了动态加载网页内容用于爬虫,所以一般也会用到phantomjs mac下如果要配置phantomjs环境的话 e ...

  10. 查看mysql 的物理存储路径

    mysql> show global variables like "%datadir%";