第4章 數(shù)據(jù)文件
本章重點討論C語言的強大功能之一 —— 磁盤輸入和輸出。多年來,最快、最簡單的專業(yè)程序都是用C語言編寫的,并且受益于C語言優(yōu)化了的文件I/O程序。
處理數(shù)據(jù)文件有時是比較困難的,本章將綜合分析這方面的一些常見問題,例如流(stream)、文件模式(文本(text)和二進制(binary))以及文件和目錄的處理等。目前,大多數(shù)專業(yè)程序是面向網絡的,因此本章末尾討論了有關文件共享和一致性控制的一些問題,希望讀者認真閱讀。此外,本章也討論了許多與文件有關的問題,例如DOS中的文件句柄和硬件錯誤處理程序的安裝。
4. 1 當errno為一個非零值時,是否有錯誤發(fā)生?
許多標準的C庫函數(shù)都通過全局變量errno向程序傳遞一個錯誤號,以表明發(fā)生哪種錯誤,但是,你的程序不應該通過檢查errno的值來判斷是否發(fā)生了錯誤。通常,被調用的標準的C庫函數(shù)都有一個返回值,該值將表示是否發(fā)生了錯誤,并且表示是否已給errno賦予了相應的錯誤號。在沒有發(fā)生錯誤或所調用的函數(shù)不使用errno時,在errno中很可能仍然保留著一個錯誤號。有時,為了改善運行速度,使用errno的函數(shù)并不將errno清零。
總之,絕對不能單憑errno的值來判斷是否發(fā)生了錯誤,而應該根據(jù)函數(shù)的返回值來判斷是否應該檢查errno的值。請參考你所使用的編譯程序的有關文檔,看看哪些函數(shù)使用了errno全局變量,以及errno的有效值清單。
4. 2 什么是流(stream)?
流是程序輸入或輸出的一個連續(xù)的字節(jié)序列,設備(例如鼠標、鍵盤、磁盤、屏幕、調制解調器和打印機)的輸入和輸出都是用流來處理的。在C語言中,所有的流均以文件的形式出現(xiàn)----不一定是物理磁盤文件,還可以是對應于某個輸入/輸出源的邏輯文件。C語言提供了5種標準的流,你的程序在任何時候都可以使用它們,并且不必打開或關閉它們。以下列出了這5種標準的流。
------------------------------------------------
名稱 描 述 例 子
------------------------------------------------
stdin 標準輸入 鍵盤
stdout 標準輸出 屏幕
stderr 標準錯誤 屏幕
stdprn 標準打印機 LPT1端口
stdaux 標準串行設備 COM1端口
------------------------------------------------
需要注意的是,stdprn和stdaux并不總是預先定義好的,因為LPT1和COM1端口在某些操作系統(tǒng)中是沒有意義的,而stdin,stdout和stderr總是預先定義好的。此外,stdin并不一定來自鍵盤,stdout也并不一定顯示在屏幕上,它們都可以重定向到磁盤文件或其它設備上。
請參見:
4.3 怎樣重定向一個標準流?
4.4 怎樣恢復一個重定向了的標準流?
4.5 stdout能被強制打印到非屏幕設備上嗎?
4.3 怎樣重定向一個標準流?
包括DOS在內的大多數(shù)操作系統(tǒng),都提供了將程序的輸入和輸出重定向到不同設備上的手段。這就是說,程序的輸出并不一定是到屏幕上,還可以重定向到文件或打印機端口上;程序的輸入并不一定來自鍵盤,還可以重定向到文件上。
在DOS中,重定向是通過重定向字符“<”和“>”來實現(xiàn)的。例如,如果你要求程序PRINTIT.EXE的輸入來自文件STRINGS.TXT,你就可以在DOS提示符下鍵入如下命令:
C:\>PRINTIT 請注意,可執(zhí)行文件的名稱總是第一個出現(xiàn)?!?”符號告訴DOS將STRINGS.TXT中的字符串作為程序PRINTIT.EXE的輸入。關于重定向stdout標準流的例子請看4. 5。
本章重點討論C語言的強大功能之一 —— 磁盤輸入和輸出。多年來,最快、最簡單的專業(yè)程序都是用C語言編寫的,并且受益于C語言優(yōu)化了的文件I/O程序。
處理數(shù)據(jù)文件有時是比較困難的,本章將綜合分析這方面的一些常見問題,例如流(stream)、文件模式(文本(text)和二進制(binary))以及文件和目錄的處理等。目前,大多數(shù)專業(yè)程序是面向網絡的,因此本章末尾討論了有關文件共享和一致性控制的一些問題,希望讀者認真閱讀。此外,本章也討論了許多與文件有關的問題,例如DOS中的文件句柄和硬件錯誤處理程序的安裝。
4. 1 當errno為一個非零值時,是否有錯誤發(fā)生?
許多標準的C庫函數(shù)都通過全局變量errno向程序傳遞一個錯誤號,以表明發(fā)生哪種錯誤,但是,你的程序不應該通過檢查errno的值來判斷是否發(fā)生了錯誤。通常,被調用的標準的C庫函數(shù)都有一個返回值,該值將表示是否發(fā)生了錯誤,并且表示是否已給errno賦予了相應的錯誤號。在沒有發(fā)生錯誤或所調用的函數(shù)不使用errno時,在errno中很可能仍然保留著一個錯誤號。有時,為了改善運行速度,使用errno的函數(shù)并不將errno清零。
總之,絕對不能單憑errno的值來判斷是否發(fā)生了錯誤,而應該根據(jù)函數(shù)的返回值來判斷是否應該檢查errno的值。請參考你所使用的編譯程序的有關文檔,看看哪些函數(shù)使用了errno全局變量,以及errno的有效值清單。
4. 2 什么是流(stream)?
流是程序輸入或輸出的一個連續(xù)的字節(jié)序列,設備(例如鼠標、鍵盤、磁盤、屏幕、調制解調器和打印機)的輸入和輸出都是用流來處理的。在C語言中,所有的流均以文件的形式出現(xiàn)----不一定是物理磁盤文件,還可以是對應于某個輸入/輸出源的邏輯文件。C語言提供了5種標準的流,你的程序在任何時候都可以使用它們,并且不必打開或關閉它們。以下列出了這5種標準的流。
------------------------------------------------
名稱 描 述 例 子
------------------------------------------------
stdin 標準輸入 鍵盤
stdout 標準輸出 屏幕
stderr 標準錯誤 屏幕
stdprn 標準打印機 LPT1端口
stdaux 標準串行設備 COM1端口
------------------------------------------------
需要注意的是,stdprn和stdaux并不總是預先定義好的,因為LPT1和COM1端口在某些操作系統(tǒng)中是沒有意義的,而stdin,stdout和stderr總是預先定義好的。此外,stdin并不一定來自鍵盤,stdout也并不一定顯示在屏幕上,它們都可以重定向到磁盤文件或其它設備上。
請參見:
4.3 怎樣重定向一個標準流?
4.4 怎樣恢復一個重定向了的標準流?
4.5 stdout能被強制打印到非屏幕設備上嗎?
4.3 怎樣重定向一個標準流?
包括DOS在內的大多數(shù)操作系統(tǒng),都提供了將程序的輸入和輸出重定向到不同設備上的手段。這就是說,程序的輸出并不一定是到屏幕上,還可以重定向到文件或打印機端口上;程序的輸入并不一定來自鍵盤,還可以重定向到文件上。
在DOS中,重定向是通過重定向字符“<”和“>”來實現(xiàn)的。例如,如果你要求程序PRINTIT.EXE的輸入來自文件STRINGS.TXT,你就可以在DOS提示符下鍵入如下命令:
C:\>PRINTIT