有时候,读写文件并不想要使用系统缓存(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. [Java] Collections的简单运用

    package test.collections; import java.util.ArrayList; import java.util.Collection; import java.util. ...

  2. Excel粘贴到textarea换行符替换

    复制到→ Excel列表的内容复制到textarea中后,前台取到的文本是这样的: chrome监视显示 console.log输出 现在需要将excel中的每行数据拼接起来用“;”隔开,方法如下: ...

  3. nyoj 70 阶乘因式分解(二)

    点击打开链接 阶乘因式分解(二) 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 给定两个数n,m,其中m是一个素数. 将n(0<=n<=2^31)的阶乘分解 ...

  4. SparkSQL On Yarn with Hive,操作和访问Hive表

    转载自:http://lxw1234.com/archives/2015/08/466.htm 本文将介绍以yarn-cluster模式运行SparkSQL应用程序,访问和操作Hive中的表,这个和在 ...

  5. unix环境C编程之日期时间转换

    1.理清概念 1.1.日历时间:   含义:国际标准时间1970年1月1日00:00:00以来经过的秒数.   数据类型:time_t.实际上是long的别名. 1.2.tm结构时间:   含义:结构 ...

  6. 项目积累——JAVA知识积累

    调用天气: <iframe src="http://www.thinkpage.cn/weather/weather.aspx?uid=&c=CHXX0008&l=zh ...

  7. RequireJS API

    可以找到许多的解读,但是原文总是最重要的,也是最正宗的说明,直接访问 RequireJS 有时不太方便,这里将 RequireJS 2.0 API 的原文转载到博客园,方便查看. This is th ...

  8. 慕课网-安卓工程师初养成-4-8 Java循环语句之 do...while

    do...while 循环与 while 循环语法有些类似,但执行过程差别比较大. 语法:  执行过程: <1>. 先执行一遍循环操作,然后判断循环条件是否成立 <2>. 如果 ...

  9. 关于 mysql 2003 客户端连接报错的处理方法

    在连接到 mysql 数据库服务器时,有时会在客户端报出 2003 的错误代码,并提示: 无法连接到服务器,但服务器却可以 ping 通,可能的原因如下: 1.网络不通.检查能不能ping通. 2.防 ...

  10. Java创建WebService服务及客户端实现

    简介 WebService是一种服务的提供方式,通过WebService,不同应用间相互间调用变的很方便,网络上有很多常用的WebService服务,如:http://developer.51cto. ...