---- 今天分享一下在linux系統在實現對文件讀寫一些基本的操作,在這之前我們要掌握一些基本的技能在Linux環境下。比如查看命令和一個函數的具體用法,就是相當於查手冊,在Linux下有一個man手冊非常有用:
man查詢手冊
man 1 +命令 這里的1表示為查詢的是Linux命令
man 2 xxx 這里的2表示為查詢的是linux api
man 3 xxx 這里的3表示為查詢的是c庫函數
在了解了這個后我們就可以開始來實現標題說的操作了。
一、在linux環境下常用文件接口函數:open、close、write、read、lseek。
二、文件操作的基本步驟分為:
a、在linux系統中要操作一個文件,一般是先open打開一個文件,得到一個文件掃描描述符,然后對文件進行讀寫操作(或其他操作),最后關閉文件即可。
b、對文件進行操作時,一定要先打開文件,然后再進行對文件操作(打開文件不成功的話,就操作不了),最后操作文件完畢后,一定要關閉文件,否則可能會造成文件損壞
c、文件平時是存放在塊設備中的文件系統中的,我們把這個文件叫做靜態文件,當我們去打開一個文件時,linux內核做的操作包括:內核在進程中建立了一個打開文件的數據結構,
記錄下我們打開的這個文件,內核在內存中申請一段內存,並且將靜態文件的內容從塊設備中讀取到內存中特定地址管理存放(叫動態文件)
d、打開文件后,以后對這個文件的讀寫操作,都是針對內存中這一份動態文件的,而不是針對靜態文件的。
當我們對動態文件進行讀寫后,此時內存中的動態文件和塊設備中的靜態文件就不同步了,
當我們close 關閉動態文件時,close內部內核將內存中的動態文件的內容去更新(同步)塊設備中的靜態文件。
三、為什么是這樣操作?
以塊設備本身有讀寫限制(回憶Nandflash、SD、等塊設備的讀寫特征),本身對塊設備進行操作非常不靈活。而內存可以按字節為單位來操作。而且進行隨機操作。
四、文件描述符是什么?
1、文件描述符:它其實實質是一個數字,這個數字在一個進程中表示一個特定的含義,當我們open打開一個文件時,操作系統在內存中構建了一些數據結構來表示這個動態文件,然后返回給應用程序一個數字作為文件描述符,這個數字就和我們內存中維護這個動態文件的這些數據結構掛鈎綁定上了。以后我們應用程序如果要操作這一個動態文件,只需要用這個文件描述符進行區分。簡單來說,它是來區分多個文件的(在打開多個文件的時候)。
2、文件描述的作用域就是當前的進程,出了這個當前進程,這個文件描述符就沒有意義了。
五、代碼實現:
1、打開文件:
1#include <stdio.h> 2#include <sys/types.h> 3#include <sys/stat.h> 4#include <fcntl.h> 5#include <unistd.h> 6int main(int argc, char *argv[]) 7{ 8 //第一步:打開文件 9 int fd=-1; //fd是文件描述符(在linux中的文件描述符fd 10 的合法范圍是0或者是一個正數,不可能是負數) 11 fd=open("a.txt",O_RDWR);//O_RDWR表示文件可讀可寫,這個可以 12 用man 手冊查看open函數的使用方法里面有它的說明 13 if(-1 ==fd)或者(fd<0) 14 { 15 printf("文件打開錯誤\n"); 16 } 17 else 18 { 19 printf("文件打開成功\n"); 20 } 21 //讀寫文件 22 //關閉文件 23 close(fd);//關閉剛才打開的文件 24 return 0; 25}
2、讀文件操作:
1#include <stdio.h> 2#include <sys/types.h> 3#include <sys/stat.h> 4#include <fcntl.h> 5#include <unistd.h> 6int main(int argc,char *argv[]) 7{ 8 int fd =-1; 9 int ret=-1; 10 char buf[100]={0}; 11 fd=open("a.txt",O_RDWR); 12 if(-1==fd) 13 { 14 printf("the open the file is failure \n"); 15 } 16 else 17 { 18 printf("the open the file is successful,fd=%d.\n",fd); 19 } 20 ret=read(fd,buf,20);//20表示讀取的字節 21 22 if(ret<-1) 23 { 24 printf("read失敗\n"); 25 } 26 else 27 { 28 printf("成功讀取了%d字節\n",ret); 29 printf("文件內容是:[%s]\n",buf); 30 } 31 close(fd); 32 return 0; 33}
代碼編譯效果:
root@ubuntu-virtual-machine:/mnt/hgfs/day# gcc file1.c
root@ubuntu-virtual-machine:/mnt/hgfs/day# ./a.out
the open the file is successful,fd=3.
成功讀取了13字節
文件內容是:[hello world!
]
3、寫文件:
1 #include <stdio.h> 2 #include <sys/types.h> 3 #include <sys/stat.h> 4 #include <fcntl.h> 5 #include <unistd.h> 6 #include <string.h> 7int main(int argc,char *argv[]) 8{ 9int fd =-1; 10char buf[100]={0}; 11char w_buf[20]="i like the mcu"; 12int ret=-1; 13fd=open("a.txt",O_RDWR); 14if(-1==fd) 15{ 16 printf("the open the file is failure \n"); 17} 18else 19{ 20 printf("the open the file is successful,fd=%d.\n",fd); 21} 22 ret=write(fd,w_buf,strlen(w_buf)); 23 if(ret<0) 24 { 25 printf("the write is failure\n"); 26 } 27else 28{ 29 printf("write successful 寫入了%d個字符\n",ret); 30} 31 ret=read(fd,buf,20);//20表示讀取的字節 32if(ret<-1) 33{ 34 printf("read失敗\n"); 35} 36else 37{ 38 printf("成功讀取了%d字節\n",ret); 39 printf("文件內容是:[%s]\n",buf); 40} 41 close(fd); 42 return 0; 43}
編譯結果:
root@ubuntu-virtual-machine:/mnt/hgfs/day# ./a.out
the open the file is successful,fd=3.
write successful 寫入了14個字符
成功讀取了0字節
文件內容是:[]
root@ubuntu-virtual-machine:/mnt/hgfs/day# cat a.txt
i like the mcuroot@ubuntu-virtual-machine:/mnt/hgfs/day# vim file1.c
這里還有一個缺陷,就是寫入的文件,在讀取的時候沒有讀取出來,這個知識點在后面會繼續學到,不要急。
六、總結:
對文件的操作,一個要知道它的操作步驟:
1、打開文件
2、讀寫文件
3、關閉文件