linux 文件io实例代码,linux 文件IO(示例代码)
1、文件描述符
(1)文件描述符的本質是一個數字,這個數字本質上是進程表中文件描述符表的一個表項,進程通過文件描述符作為index去索引查表得到文件表指針,再間接訪問得到這個文件對應的文件表。
(2)文件描述符這個數字是open系統調用內部由操作系統自動分配的,操作系統分配這個fd時也不是隨意分配,也是遵照一定的規律的,我們現在就要研究這個規律。
(3)操作系統規定,fd從0開始依次增加。fd也是有最大限制的,在linux的早期版本中(0.11)fd最大是20,所以當時一個進程最多允許打開20個文件。linux中文件描述符表是個數組(不是鏈表),所以這個文件描述符表其實就是一個數組,fd是index,文件表指針是value
(4)當我們去open時,內核會從文件描述符表中挑選一個最小的未被使用的數字給我們返回。也就是說如果之前fd已經占滿了0-9,那么我們下次open得到的一定是10.(但是如果上一個fd得到的是9,下一個不一定是10,這是因為可能前面更小的一個fd已經被close釋放掉了)
(5)fd中0、1、2已經默認被系統占用了,因此用戶進程得到的最小的fd就是3了。
(6)linux內核占用了0、1、2這三個fd是有用的,當我們運行一個程序得到一個進程時,內部就默認已經打開了3個文件,這三個文件對應的fd就是0、1、2。這三個文件分別叫stdin、stdout、stderr。也就是標準輸入、標準輸出、標準錯誤。
(7)標準輸入一般對應的是鍵盤(可以理解為:0這個fd對應的是鍵盤的設備文件),標準輸出一般是LCD顯示器(可以理解為:1對應LCD的設備文件)
(8)printf函數其實就是默認輸出到標準輸出stdout上了。stdio中還有一個函數叫fpirntf,這個函數就可以指定輸出到哪個文件描述符中。
2、常用API
open、close、write、read、lseek
2.1OPEN
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode)
const char *pathname為需要打開的文件、
flags通過一些宏設置讀寫權限
O_RDONLY、 O_WRONLY 、O_RDWR(只讀 只寫 讀寫)
O_APPEND?O_APPEND屬性去打開文件時,如果這個文件中本來是有內容的,則新寫入的內容會接續到原來內容的后面
O_TRUNC ?O_TRUNC屬性去打開文件時,如果這個文件中本來是有內容的,則原來的內容會被丟棄。
O_CREAT ??O_CREAT若不存在則創建。open函數在使用O_CREAT標志去創建文件時,可以使用第三個參數mode來指定要創建的文件的權限。mode使用4個數字來指定權限的,其中后面三個很重要,對應我們要創建的這個文件的權限標志。譬如一般創建一個可讀可寫不可執行的文件就用0666
O_EXCL ?加上O_EXCL如果文件已經被打開則打開失敗
O_NONBLOCK 默認為阻塞模式。添加這個設置為非阻塞模式
O_SYNC?write阻塞等待底層完成寫入才返回到應用層。
2.2 read
ssize_t read(int fd, void *buf, size_t count);
2.3 write
ssize_t write(int fd, const void *buf, size_t count);
2.3lseek
執行read與write函數都會使文件指針移動。lseek函數可以調整文件指針。
off_t lseek(int fd, off_t offset, int whence);
參數解釋。第一個代表文件描述符、第二個代表移動個數、第三個設置移動頭。
lseek(fd, 0 ,SEEK_SET);//文件指針指向頭
SEEK_SET代表指向頭
SEEK_END代表尾部
SEEK_CUR代表當前位置
3.3close
可以通過close關閉打開的文件描述符。
3.4dup和dup2函數
(1)dup系統調用對fd進行復制,會返回一個新的文件描述符(譬如原來的fd是3,返回的就是4)
(2)dup系統調用有一個特點,就是自己不能指定復制后得到的fd的數字是多少,而是由操作系統內部自動分配的,分配的原則遵守fd分配的原則
(3)dup2和dup的作用是一樣的,都是復制一個新的文件描述符。但是dup2允許用戶指定新的文件描述符的數字。
3.5fcntl的原型和作用
fcntl函數是一個多功能文件管理的工具箱,接收2個參數+1個變參。第一個參數是fd表示要操作哪個文件,第二個參數是cmd表示要進行哪個命令操作。變參是用來傳遞參數的,要配合cmd來使用。
4、標準IO庫介紹
4.1、標準IO和文件IO有什么區別
(1)看起來使用時都是函數,但是:標準IO是C庫函數,而文件IO是linux系統的API
(2)C語言庫函數是由API封裝而來的。庫函數內部也是通過調用API來完成操作的,但是庫函數因為多了一層封裝,所以比API要更加好用一些。
(3)庫函數比API還有一個優勢就是:API在不同的操作系統之間是不能通用的,但是C庫函數在不同操作系統中幾乎是一樣的。所以C庫函數具有可移植性而API不具有可移植性。
(4)性能上和易用性上看,C庫函數一般要好一些。譬如IO,文件IO是不帶緩存的,而標準IO是帶緩存的,因此標準IO比文件IO性能要更高。
4.2、常用標準IO函數介紹
(1)常見的標準IO庫函數有:fopen、fclose、fwrite、fread、ffulsh、fseek
#include #include#include#include#include#include
int main(int argc , char *argv[])
{int fd=-1; //fd 文件描述符
char buf[100]={0};//字符緩沖區
char writebuf[20]="ilovezw";//字符緩沖區
intret;//第一步打開//fd = open ("a.txt",O_RDWR|O_APPEND);
fd = open ("a.txt",O_RDWR);if(-1 ==fd)
{
perror("文件打開錯誤");
_exit(-1);
}else{
printf("文件打開成功,fd=%d.\n",fd);
}//lseek(fd, 3 ,SEEK_SET);//光標位移3//第二步讀寫
ret=write(fd,writebuf,strlen(writebuf));//寫函數
if(-1==ret)
{//printf("write error");
perror("write error");
_exit(-1);
}else{
printf("ret=%d\n",ret);//lseek(fd, -ret ,SEEK_SET);//光標位移3
}
lseek(fd,0 ,SEEK_SET);//文件指針指向頭
ret=read(fd,buf,20);//讀文件
if(-1==ret)
{//printf("read error");
perror("read error");
_exit(-1);
}else{
printf("ret=%d,a.txt=%s\n",ret,buf);
}//第三步關閉
close(fd);return 0;
}
/*標準IO
*/
#include#include#include
int main(int argc,char *argv[])
{
FILE*fp =NULL;char buf[10];
fp= fopen("1.txt","r+");if(NULL ==fp)
{
perror("fopen");
exit(-1);
}
memset(buf,0,sizeof(buf));
fwrite("12345",1,5,fp);
fseek( fp,0, SEEK_SET );
fread(buf,1,5,fp);
printf("%s\n",buf);
fclose(fp);return 0;
}
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的linux 文件io实例代码,linux 文件IO(示例代码)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux+卸载+gpm服务,Linux
- 下一篇: linux 其他常用命令