c文件i/o操作的詳細介紹,以下是關于如何使用c語言進行文件i/o操作的詳細指南,包括文件描述符、重定向、文件緩沖區等概念的講解。
#include <stdio.h> <p>int main() { FILE<em> fp = fopen("log.txt", "w"); if (fp == NULL) { perror("fopen"); return 1; } fclose(fp); return 0; }
文件描述符和open函數:
可以認為,f#系列的函數是對系統調用的封裝,方便進行二次開發。
文件描述符fd:
在操作系統內,系統在訪問文件時,只認文件描述符fd。
read和stat函數:
Struct stat是一個內核結構體,可以直接使用。stat的第二個參數是一個輸出型參數,我們將參數傳進去后,它會把參數填滿然后再傳出來。
read的第一個參數指讀取的文件fd,第二個參數是將讀取到的內容放到該緩沖區中,第三個參數是要讀取的字節數。read的返回值:>0 表示讀取到的字節數;=0 表示已經讀取到文件末尾。
文件描述符的分配規則:
因為文件描述符0、1、2默認是打開的,所以這里結果是3。如果我們先把描述符0關了再打開新文件會怎樣呢?
重定向:
如果我們先把1關閉,發現結果什么也不打印。這是因為文件描述符1是標準輸出流,關閉后,就不會在顯示器打印了。
運行上面代碼,發現什么也沒打印,但確實創建了新的文件log.txt。打印該文件,發現內容寫在了文件里面。然后就發現log.txt里面存著這些內容。
log.txt存在磁盤中,當進程啟動打開時,就會被加載到內存中。由于我們先關閉了文件描述符1,所以此時log.txt的文件描述符就是1。上層的printf和fprintf都是向stdout打印,而stdout的描述符是1,OS只認文件描述符,所以最終就向log.txt打印了內容。重定向的本質:是在內核中改變文件描述符表特定下標的內容,與上層無關!每個文件對象都有對應的內核文件緩沖區,我們寫數據都是從上層通過文件描述符1,寫到對應的文件緩沖區,然后OS再把內容刷新到磁盤的文件中。stdin、stdout、stderr都是FILE結構體,里面除了封裝著fd,還有語言級別的文件緩沖區。所以我們通過printf/fprintf不是直接寫到OS的內部的緩沖區,而是直接寫到語言級別的緩沖區中,然后c語言再通過1號文件描述符把內容刷新到OS的內核文件緩沖區中。所以fflush()里面是stdout,這是因為我們是刷新語言級別緩沖區的內容到OS的內核緩沖區中,內核緩沖區的內容由OS進行刷新。
如果我們把close也注釋掉,結果如下:
return的時候,語言級別緩沖區的內容就被沖刷到內核文件緩沖區中,此時log.txt就有內容了。
使用dup2系統調用:
如果我們要對標準輸出進行重定向,把往顯示器打印的內容變成往log.txt打印,根據上面的參數解釋,參數的填法應該是dup2(fd,1)。也就是把oldfd留下來,拷貝給newfd。
運行上面代碼,發現不在顯示器上打印,而是在log.txt里打印。
緩沖區的刷新策略:
直接運行代碼,會全部打印在顯示器上。我們可以重定向到不同文件,這樣就可以將正確信息和錯誤信息分出來。這也是fd1,fd2的意義。上面是完整的重定向的寫法。
如果我們想把1和2都重定向到同一個文件中,可以通過上面的寫法實現。
最后,感謝你耐心閱讀這篇文章,并感謝我能夠堅持寫到這里,送幾句話給你和我:
- 一個冷知識:屏蔽力是一個人最頂級的能力,任何消耗你的人和事,多看一眼都是你的不對。
- 你不用變得很外向,內向挺好的,但需要你發言的時候,一定要勇敢。正所謂:君子可內斂不可懦弱,面不公可起而論之。
- 成年人的世界,只篩選,不教育。
- 自律不是6點起床,7點準時學習,而是不管別人怎么說怎么看,你也會堅持去做,絕不打亂自己的節奏,是一種自我的恒心。
- 你開始炫耀自己,往往都是災難的開始,就像老子在《道德經》里寫到:光而不耀,靜水流深。
最后,如果覺得我寫的還不錯,請不要忘記點贊?,收藏?,加關注?哦(??ω??)。
愿我們一起加油,奔向更美好的未來,愿我們從懵懵懂懂的一枚菜鳥逐漸成為大佬。加油,為自己點贊!