五、文件IO函数
對(duì)于傳統(tǒng)的操作系統(tǒng)來(lái)說(shuō),普通的 I/O 操作一般會(huì)被內(nèi)核緩存,這種 I/O 被稱作緩存I/O。本文所介紹的文件訪問(wèn)機(jī)制不經(jīng)過(guò)操作系統(tǒng)內(nèi)核的緩存,數(shù)據(jù)直接在磁盤和應(yīng)用程序地址空間進(jìn)行傳輸,所以該文件訪問(wèn)的機(jī)制稱作為直接 I/O。Linux 中就提供了這樣一種文件訪問(wèn)機(jī)制,對(duì)于那種將 I/O 緩存存放在用戶地址空間的應(yīng)用程序來(lái)說(shuō),直接 I/O 是一種非常高效的手段。
一、打開(kāi)文件函數(shù)open
- int open(const char *path, int oflags);
- int open(const char *path, int oflags,mode_t mode);
? ? ?– 參數(shù)path表示:路徑名或者文件名。路徑名為絕對(duì)路徑名。
? ? ?– 參數(shù)oflags表示:打開(kāi)文件所采取的動(dòng)作?O_RDONLY文件只讀;O_WRONLY文件只寫;O_RDWR文件可讀可寫;
? ? ? ? O_NOCTTY如果路徑指向終端,則不將設(shè)備作為此進(jìn)程的控制終端 ;O_NDELAY非阻塞方式操作文件。
? ? ?– mode表示:設(shè)置創(chuàng)建文件的權(quán)限。權(quán)限的宏定義很麻煩,可以直接用數(shù)字(777)替代。
? ? ?– 返回值:出錯(cuò)返回-1;否則返回文件句柄。
我們?cè)趆ome/linuxsystemcode/io_file目錄下創(chuàng)建open.c文件,具體代碼如下:
#include <stdio.h>#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>main(){int fd;char *leds = "/dev/leds"; // 存在的文件 char *test1 = "/bin/test1"; // 不存在的文件char *test2 = "/bin/test2"; // 不存在的文件,我們以O(shè)_CREAT的形式打開(kāi)if((fd = open(leds,O_RDWR|O_NOCTTY|O_NDELAY))<0){printf("open %s failed!\n",leds);}printf("\n%s fd is %d\n",leds,fd);if((fd = open(test1,O_RDWR,0777))<0){printf("open %s failed!\n",test1);}printf("%s fd is %d\n",test1,fd); if((fd = open(test2,O_RDWR|O_CREAT,0777))<0){printf("open %s failed!\n",test2);}printf("%s fd is %d\n",test2,fd); }?然后使用GCC編譯器編譯:
最后拷貝出open文件,放到U盤,然后運(yùn)行,具體如下圖:?
[ 5636.146944] LEDS_CTL DEBUG:Device Opened Success!
[ 5636.151300] LEDS_CTL DEBUG:Device Closed Success!? ? ? ? ? ? 為內(nèi)核提示的打開(kāi)和關(guān)閉文件成功。
?/dev/leds fd is 3? ? ? ? ? ? ? leds的文件句柄是3
open /bin/test1 failed!? ? ? test1打開(kāi)失敗
/bin/test1 fd is -1? ? ? ? ? ? ?test1失敗,返回-1;
/bin/test2 fd is 4? ? ? ? ? ? ? test2創(chuàng)建并打開(kāi)成功,文件句柄為4;
二、創(chuàng)建文件函數(shù)create和open
- int creat(const char * pathname, mode_t mode);//注意,這個(gè)沒(méi)寫錯(cuò),就是creat
? ? ? ? ?– 參數(shù)path表示:路徑名或者文件名。路徑名為絕對(duì)路徑名。
? ? ? ? ?– 參數(shù)oflags表示:打開(kāi)文件所采取的動(dòng)作:?O_RDONLY文件只讀;O_WRONLY文件只寫;O_RDWR文件可讀可寫
我們?cè)趆ome/linuxsystemcode/io_file目錄下創(chuàng)建creat.c文件,具體代碼如下:?
//標(biāo)準(zhǔn)輸入輸出頭文件 #include <stdio.h>//文件操作函數(shù)頭文件 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>main() {int fd;//開(kāi)發(fā)板中已經(jīng)存在/dev/leds文件char *leds = "/dev/leds";//開(kāi)發(fā)板中不存在的文件/bin/test1char *test1 = "/bin/test1";//開(kāi)發(fā)板中不存在的文件/bin/test2char *test2 = "/bin/test2";//需要新建的文件/bin/test3char *test3 = "/bin/test3";//使用open函數(shù)打開(kāi)文件if((fd = open(leds, O_RDWR|O_NOCTTY|O_NDELAY))<0){printf("open %s failed\n",leds); }printf("%s fd is %d\n",leds,fd);//使用open函數(shù)打開(kāi)不存在的文件,不添加O_CREAT標(biāo)識(shí)符,會(huì)報(bào)錯(cuò)if((fd = open(test1, O_RDWR))<0){printf("open %s failed\n",test1); }//打開(kāi)文件創(chuàng)建文件,添加標(biāo)志位O_CREAT表示不存在這個(gè)文件則創(chuàng)建文件if((fd = open(test2, O_RDWR|O_CREAT,0777))<0){printf("open %s failed\n",test2); }printf("%s fd is %d\n",test2,fd);fd = creat(test3,0777);if(fd = -1){printf("%s fd is %d\n",test3,fd);}else{printf("create %s is succeed\n",test3);} }和上面openy一樣編譯,然后靠到U盤里,插入開(kāi)發(fā)板運(yùn)行:
?
三、寫函數(shù)write
- ssize_t? write(int fd, const void *buf, size_t count);
? ? ? ? ?– 參數(shù)fd表示:使用open 函數(shù)打開(kāi)文件之后返回的句柄。
? ? ? ? ?– 參數(shù)*buf表示:寫入的數(shù)據(jù)
? ? ? ? ?– 參數(shù)count表示:最多寫入字節(jié)數(shù)
? ? ? ? ?– 返回值:出錯(cuò)-1,;其它數(shù)值表示實(shí)際寫入的字節(jié)數(shù)
具體程序如下:
//標(biāo)準(zhǔn)輸入輸出頭文件 #include <stdio.h>//文件操作函數(shù)頭文件 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <string.h>main() {int fd;char *testwrite = "/bin/testwrite";ssize_t length_w;char buffer_write[] = "Hello Write Function!";if((fd = open(testwrite, O_RDWR|O_CREAT,0777))<0){printf("open %s failed\n",testwrite); }//將buffer寫入fd文件length_w = write(fd,buffer_write,strlen(buffer_write));if(length_w == -1){perror("write");}else{printf("Write Function OK!\n");}close(fd); }運(yùn)行效果如下:?
?
四、文件的讀取函數(shù)read
- ssize_t? read(int fd,void *buf,size_t len);
? ? ? ?– 參數(shù)fd:使用open 函數(shù)打開(kāi)文件之后返回的句柄
? ? ? ?– 參數(shù)*buf:讀出的數(shù)據(jù)保存的位置
? ? ? ?– 參數(shù)len:每次最多讀len 個(gè)字節(jié)
? ? ? ?– 返回值:錯(cuò)誤返回-1,執(zhí)行成功返回實(shí)際讀取值
具體程序如下:
//標(biāo)準(zhǔn)輸入輸出頭文件 #include <stdio.h>//文件操作函數(shù)頭文件 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <string.h>#define MAX_SIZE 1000main(){int fd;ssize_t length_w,length_r = MAX_SIZE,ret;char *testwrite = "/bin/testwrite";char buffer_write[] = "Hello Write Function!";char buffer_read[MAX_SIZE];if((fd = open(testwrite,O_RDWR|O_CREAT,0777))<0){printf("open %s failed!\n",testwrite);}length_w = write(fd,buffer_write,strlen(buffer_write));if(length_w == -1){perror("write");}else{printf("Write Function OK!\n");}close(fd);if((fd = open(testwrite,O_RDWR|O_CREAT,0777))<0){printf("open %s failed!\n",testwrite);}if(ret = read(fd,buffer_read,length_r)){perror("read");}printf("Files Content is %s \n",buffer_read);close(fd); }?運(yùn)行效果如下:
五、關(guān)閉函數(shù)close
- int close(int fd);
? ? ? ?– 參數(shù)fd:使用open 函數(shù)打開(kāi)文件之后返回的句柄。
參考上面write程序最后一行。
最后,我把我們實(shí)驗(yàn)過(guò)程的源碼和生成的文件打包一起,需要可以下載(沒(méi)積分留言,我發(fā)給你):
?
?
總結(jié)
- 上一篇: 四、linux基础知识
- 下一篇: 六、字符设备控制