昨天偵錯工具得時候發現,調用一個copy函數,產生得檔案和源檔案總是不一致,於是去檢查copy函數,最後查出問題,fopen裡面沒有採用二進位方式開啟,那麼預設得就是文本方式。
轉一個關於二進位和文本方式開啟得區別
《fopen 文字檔與二進位檔案區別》
http://hi.baidu.com/assslove/blog/item/d0b727ea014ee3dbd539c9e8.html
在學習C語言檔案操作後,我們都會知道開啟檔案的函數是fopen,也知道它的第二個參數是 標誌字串。其中,如果字串中出現'b',則表明是以開啟二進位(binary)檔案,否則是開啟文字檔。
那麼什麼是文字檔,什麼是二進位檔案呢? 可能大多數人都沒有仔細考慮過。
在Windows和DOS系統中,狹義的文字檔是指副檔名為txt的檔案。實際上,那些沒有規定格式的,由可理解的的ASCII以及其他編碼文字組成的檔案都是文字檔,如C來源程式檔案,HTML超文本,XML。除此之外的其他檔案都是二進位檔案,如Word檔案DOC,圖象格式檔案JPG。
但是,所謂使用fopen標誌開啟文字檔與二進位檔案的說法並不準確。正確的說法應該是--以文本方式和二進位方式開啟檔案。因為我們用兩種方式都可以任意的檔案。
即使這樣,為什麼還要區分兩種方式呢?
這是因為這兩種方式在讀寫檔案時的操作是不一樣的。
二進位方式很簡單,讀檔案時,會原封不動的讀出檔案的全部內容,寫的時候,也是把內存緩衝區的內容原封不動的寫到檔案中。
而文本方式就不一樣了,在寫檔案時,會將分行符號號CRLF(0x0D 0x0A)全部轉換成單個的0x0A,並且當遇到結束符CTRLZ(0x1A)時,就認為檔案已經結束。相應的,寫檔案時,會將所有的0x0A換成0x0D0x0A。
所以,若使用文本方式開啟二進位檔案時,就很容易出現檔案讀不完整,或內容不對的錯誤。即使是用文本方式開啟文字檔,也要謹慎使用,比如複製檔案,就不應該使用文本方式。
要特別注意的是,上面這樣的說法僅適用於DOS和Windows系統。在Unix和其他一些系統中,沒有文本方式和二進位方式的區分,使不使用'b'標誌都是一樣的。這是由於不同作業系統對文字檔分行符號的定義,和C語言中分行符號的定義有所不同而造成的。
如上文已提到,DOS和Windows系統使用CRLF(0x0D 0x0A)雙位元組作為文字檔分行符號,而Unix文字檔的分行符號只有一個位元組LF(0x0A)為。在C語言中,也是以LF即'/n'為分行符號。
由於DOS/Windows定義的分行符號和C語言的不一致,C語言的標準輸入輸出函數適行讀寫文字檔時,就適行了CRLF->LF的轉換。而Unix的定義和C語言的是一樣的,就不必轉換了。
那麼,為什麼會有定義不一致的情況呢,這純屬曆史原因。當初C是在Unix上發展的,對換行的定義自然就一樣了。其後C被引入到DOS系統,為了使原有的C程式能不加修改的讀寫DOS的文字檔,所以就在檔案讀寫上做了修改。隨著DOS/Windows成為主流平台,這個當初為了相容而做的修改給眾多的C語言開發人員添了這樣一個小小的麻煩。