Sometimes, read and write files do not want to use the system cache (page cache), when the direct file read and write comes in handy, using the method:
(1) When opening the file, add the O_direct parameter:
You need to define _GNU_SOURCE, otherwise you cannot find the O_direct macro definition
Sample fragment:
#define _gnu_source <sys/types.h><sys/stat.h>int FD = Open ("test.out"0644);
View Code
(2) The transfer data size and buffer address of the read-write operation need to be aligned according to certain rules:
Under Linux, for different file systems and kernel versions, different alignment boundaries are required, and there is no unified interface to get that boundary value.
For kernel version 2.4: The transfer size and buffer address need to be aligned according to the logical block size of the Access file system, such as the file system block size is 4k,buffer address needs to be aligned according to 4K, need to read and write 4K multiples of data
For kernel 2.6: The transfer size and buffer address are aligned according to the sector size of the target storage device (general 512)
You can use Memalign (malloc.h) to assign a resource interface with the specified address alignment: void *memalign (size_t boundary, size_t size);
Complete sample program:
#define_gnu_source#include<sys/types.h>#include<fcntl.h>#include<malloc.h>#include<stdio.h>#include<errno.h>#include<string.h>intMainvoid) { CharHello_str[] ="Hello world!"; void*Write_buffer; void*Read_buffer; intFD; intRET =0; FD= Open ("Test.out", O_RDWR | O_creat | O_direct,0644); if(FD <0) {printf ("Failed to open file\n"); returnFD; } /*allocate a 1024x768 bytes buffer*/Write_buffer= Memalign ( +, +*2);//Align by if(!Write_buffer) {printf ("Failed to alloc write buffer\n"); RET= -Enomem; GotoBad_write_buffer; } memcpy (Write_buffer, Hello_str,sizeof(HELLO_STR)); RET= Write (fd, Write_buffer, +*2); if(Ret <0) {printf ("Failed to write file\n"); GotoBad_write; } lseek (FD,0, Seek_set);//read previous write DataRead_buffer= Memalign ( +, +*2); if(!Read_buffer) {printf ("Failed to alloc read buffer\n"); RET= -Enomem; GotoBad_read_buffer; } ret= Read (FD, Read_buffer, +*2); if(Ret <0) {printf ("Failed to read file\n"); GotoBad_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) ; returnret;}
View Code
Quote Linus Words:
"The thing that have always disturbed me about o_direct are that the whole interface are just stupid, and was probably design Ed by a deranged monkey on some serious mind-controlling substances. " -linus (O_direct is a lump of excrement)
Ps:
For a detailed description of the O_direct, you can see the documentation for the Linux open system call: http://man7.org/linux/man-pages/man2/open.2.html
Linux Direct File read/write (file Dio)