有時候,讀寫文件並不想要使用系統緩存(page cache),此時 direct 文件讀寫就派上了用場,使用方法:html
(1)打開文件時,添加O_DIRECT參數:linux
須要定義_GNU_SOURCE,不然找不到O_DIRECT宏定義緩存
示例片斷:ide
#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, 0644);
(2)讀寫操做的傳輸數據大小和緩衝區地址都須要按照必定的規則對齊:spa
Linux下,對於不一樣的文件系統和內核版本,須要的對齊邊界不一樣,也沒有統一的接口能夠獲取到該邊界值。code
對於kernel 2.4版本:傳輸大小和緩衝區地址均須要按照訪問文件系統的邏輯塊大小對齊,好比文件系統的塊大小是4K,buffer地址須要按照4K對齊,須要讀寫4K倍數的數據htm
對於kernel 2.6版本:傳輸大小和緩衝區地址按照目標存儲設備的扇區大小(通常512)對齊blog
可以使用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 = 0; fd = open("test.out", O_RDWR | O_CREAT | O_DIRECT, 0644); if (fd < 0) { printf("Failed to open file\n"); return fd; } /* allocate a 1024 bytes buffer */ write_buffer = memalign(512, 512 * 2); // 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, 512 * 2); if (ret < 0) { printf("Failed to write file\n"); goto bad_write; } lseek(fd, 0, SEEK_SET); // read previous write data read_buffer = memalign(512, 512 * 2); if (!read_buffer) { printf("Failed to alloc read buffer\n"); ret = -ENOMEM; goto bad_read_buffer; } ret = read(fd, read_buffer, 512 * 2); if (ret <0) { 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