有时候,读写文件并不想要使用系统缓存(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. mysql 实现oracle start with connect by递归

    在Oracle 中我们知道有一个 Hierarchical Queries 通过CONNECT BY 我们可以方便的查了所有当前节点下的所有子节点.但很遗憾,在MySQL的目前版本中还没有对应的功能. ...

  2. [ActionScript] AS3代码实现渐变遮罩效果

    import flash.display.Shape; import flash.display.GradientType; import flash.geom.Matrix; import flas ...

  3. Java UDP网络编程 - 最简单示例

    UDP也是网络通讯中的一个重要协议,与TCP区别可参见浅谈TCP/IP 和 UDP的区别,本文就对Java UDP通讯做一个简单例子介绍 服务端: package wyf; import java.i ...

  4. Dubbo 服务暴露注册流程

    Dubbo的应用会在启动时完成服务注册或订阅(不论是生产者,还是消费者)如下图所示. 图中小方块Protocol, Cluster, Proxy, Service, Container, Regist ...

  5. MongoDB相关资料收集

    MongoDB 入门教程http://www.runoob.com/mongodb/mongodb-tutorial.html .net 驱动程序下载:http://mongodb.github.io ...

  6. (转)ASP.NET MVC4 部署错误 Could not load file or assembly

    使用VS2010 测试ASP.NET MVC 4 Web API 在部署时候遇到了问题,发现园友有解决的方式,因此转载.         我的解决方式有两种:使用VS2015将VS2010的项目重新发 ...

  7. QTEmbedded VCN实现

    1 在QT在第三方插件里加入VNC 进入\src\plugins\gfxdrivers\vnc,qmake -------make--------- make install 把目标文件夹gfxdri ...

  8. excel中 lookup的使用

    问题来源: 有一批数据要处理,excel格式,第一个表是 名字,第二个是“姓名”和“顾问”, 每一列执行以下操作,从名字列找到名字,然后在第二个表中找到该姓名对应的“顾问”,粘贴到 第一个表名字的后面 ...

  9. Rman-03002,Rman-12010,Rman-12012

    为什么会出现如此的错误呢? 答:因为我们在分配通道时设备类型分配为磁带,但是你并没有安装磁带设备,所以就会出现这样的错误. 错误如下: 解决方法: 登陆你的目标数据库,重新进行设置,命令如下: con ...

  10. Laxcus大数据管理系统2.0(11)- 第九章 容错

    第九章 容错 在当前,由于集群庞大的组织体系和复杂性,以及用户普遍要求低成本硬件,使得集群在运行过程中发生的错误概率,远远高于单一且性能稳定的小型机服务器,并且集群在运行过程中几乎是不允许停止的,这就 ...