我們對文件的概念已經非常熟悉了,比如常見的 Word 文檔、txt 文件、源文件等。文件是數據源的一種,最主要的作用是保存數據。
在操作系統中,為了統一對各種硬件的操作,簡化接口,不同的硬件設備也都被看成一個文件。對這些文件的操作,等同於對磁盤上普通文件的操作。例如,通常把顯示器稱為標准輸出文件,printf 就是向這個文件輸出,把鍵盤稱為標准輸入文件,scanf 就是從這個文件獲取數據。
常見硬件設備與文件的對應關系
文件 |
硬件設備 |
stdin
標准輸入文件,一般指鍵盤;scanf()、getchar() 等函數默認從 stdin 獲取輸入。
stdout
標准輸出文件,一般指顯示器;printf()、putchar() 等函數默認向 stdout 輸出數據。
stderr
標准錯誤文件,一般指顯示器;perror() 等函數默認向 stderr 輸出數據(後續會講到)。
stdprn
標准打印文件,一般指打印機。
我們不去探討硬件設備是如何被映射成文件的,大家只需要記住,在C語言中硬件設備可以看成文件,有些輸入輸出函數不需要你指明到底讀寫哪個文件,系統已經為它們設置了默認的文件,當然你也可以更改,例如讓 printf 向磁盤上的文件輸出數據。
操作文件的正確流程為:打開文件 --> 讀寫文件 --> 關閉文件。文件在進行讀寫操作之前要先打開,使用完畢要關閉。
所謂打開文件,就是獲取文件的有關信息,例如文件名、文件狀態、當前讀寫位置等,這些信息會被保存到一個 FILE 類型的結構體變量中。關閉文件就是斷開與文件之間的聯系,釋放結構體變量,同時禁止再對該文件進行操作。
在C語言中,文件有多種讀寫方式,可以一個字符一個字符地讀取,也可以讀取一整行,還可以讀取若干個字節。文件的讀寫位置也非常靈活,可以從文件開頭讀取,也可以從中間位置讀取。
文件流
在《載入內存,讓程序運行起來》一文中提到,所有的文件(保存在磁盤)都要載入內存才能處理,所有的數據必須寫入文件(磁盤)才不會丟失。數據在文件和內存之間傳遞的過程叫做文件流,類似水從一個地方流動到另一個地方。數據從文件復制到內存的過程叫做輸入流,從內存保存到文件的過程叫做輸出流。
文件是數據源的一種,除了文件,還有數據庫、網絡、鍵盤等;數據傳遞到內存也就是保存到C語言的變量(例如整數、字符串、數組、緩沖區等)。我們把數據在數據源和程序(內存)之間傳遞的過程叫做數據流(Data Stream)。相應的,數據從數據源到程序(內存)的過程叫做輸入流(Input Stream),從程序(內存)到數據源的過程叫做輸出流(Output Stream)。
輸入輸出(Input output,IO)是指程序(內存)與外部設備(鍵盤、顯示器、磁盤、其他計算機等)進行交互的操作。幾乎所有的程序都有輸入與輸出操作,如從鍵盤上讀取數據,從本地或網絡上的文件讀取數據或寫入數據等。通過輸入和輸出操作可以從外界接收信息,或者是把信息傳遞給外界。
我們可以說,打開文件就是打開了一個流。