小小換行符亂談 文字檔案vs二進位制檔案

2021-05-25 09:41:38 字數 4166 閱讀 9667

"b"

"binary"

"u" 或 "ru"

qiodevice::text...

如此種種,看起來是如此的複雜,難怪很多剛接觸程式設計的網友都不相信(或者不想相信):

是啊,乙個小小的換行符值得如此大動干戈麼?

哎,等等...

你前面提的c中的"b",c++中的"fstream::binary",qt的"qfile::text",我都知道啊:不是區分文字和二進位制操作的麼?和換行符有什麼關係?!

那麼我們有必須要看看:

如果這樣,為何c、c++等等開啟檔案是都提供文字和二進位制兩種模式麼?(暫不解釋^_^)

考慮乙個例子:開啟檔案(不管字尾名等等),分別寫入:

"/x10/x11/x12/x13/x14"

不可見字元

"/x30/x31/x32/x33/x34"

"01234"

而後者由於全部是可列印字元,你可能就會稱其為文字檔案。

注意區分兩個概念:當我們提c、c++開啟檔案的方式時,我們一直在說 文字模式 和二進位制模式,而不是說開啟 檔案檔案 和二進位制檔案。這中間有很微妙的區別。

任何乙個檔案,你都可以用文字或二進位制模式開啟。但是對於 *.png 等這些東西,你用文字模式開啟讀進來的往往不是你期望的結果。

考慮這樣乙個檔案 hello.txt,其內容:

line1/r/nline2/r/n
如果在windows下:你用文字模式開啟,讀進來多少個字元?用二進位制模式開啟,又是多少個字元?為何同乙個檔案,讀進來的不一樣?

我們前面提到(c、c++、python、還有不該和語言並列qt)的檔案操作,都是需要通過系統呼叫對檔案進行操作的。具體一點:

handle winapi createfile(

__in lpctstr lpfilename,

__in dword dwdesiredaccess,

__in dword dwsharemode,

__in_opt lpsecurity_attributes lpsecurityattributes,

__in dword dwcreationdisposition,

__in dword dwflagsandattributes,

__in_opt handle htemplatefile

);

引數很多,每乙個引數又有很多標記位組成(具體看msdn)。但是你可以發現:對它來說,不存在文字檔案和二進位制檔案的區別,你也無法設定text或binary等標記位!!

int open(const char *pathname, int flags);

int open(const char *pathname, int flags, mode_t mode);

int creat(const char *pathname, mode_t mode);

同樣,這兒可以設定flags和mode,可以設定的標記很多。但是就是沒有提供text和binary相關的東西!!

是不是很有意思?

換行符應用程式和作業系統通常用1到2個字元代表換行:

cr+lf

windows、dos、symbian、palm ...

lf

gnu/linux、mac os x、freebsd ...

cr

mac os 9(之前)...

lf+cr

acom bbc

rs

qnx 在posix之前

nel

z/os、i5/os ...

......

這些之中,其實我們也只對 cr+lf 與 lf 這兩種換行符感興趣。

本來一切很正常的:

在windows下:

在posix系統下

各個平台相安無事,windows下你想換行就用'/r/n',posix下想換行就用'/n'

各個平台的換行符不一致,一旦涉及跨平台問題就出來了。

考慮一下,如果使用c語言的binary模式的話,我們想生成乙個像前面一樣包含兩行**的檔案,該怎麼辦?

應該就是為了這個吧,引入了乙個"文字模式"

正是為了這個換行符,所以c、c++、python等語言提供的檔案操作函式才都有了text、binary兩種模式:

#include file *fopen(const char * restrict filename, const char * restrict mode);
除了檔名之外,還要傳遞乙個 mode 的字串作為標記。而這些標記分為帶b和不帶b兩類:

文字二進位制

r

rb

唯讀或只寫

檔案必須存在

w

wb

檔案存在則清空、不存在則建立

a

ab

追加;檔案不存在則建立

r+

rb+讀寫

同r和rb

w+

w+b或 wb+

同w和wb

a+

a+b或 ab+

同a和ab

explicit fstream ( const char * filename,ios_base::openmode mode = ios_base::in | ios_base::out );
除了檔名之外,我們需要傳遞乙個 mode:

ate

(at end) 開啟檔案後立即將檔案定位到檔案尾

binary

(binary) 以二進位制模式進行io操作

in

(input) 允許讀操作

out

(output) 允許寫操作

trunc

(truncate) 開啟檔案時清空檔案流

這樣看似乎沒神馬意思哈?一般都是組合使用的:

out只寫

清空檔案內容 追加

out|trunc

等同out

in唯讀

in|out讀寫

in|out|trunc

清空檔案內容

bool qfile::open ( openmode mode )
這兒是mode又是什麼東西?

qiodevice::notopen

qiodevice::readonly

qiodevice::writeonly

qiodevice::readwrite

qiodevice::truncate

qiodevice::text

qiodevice::unbuffered

現在國內用linux的似乎越來越多了,很多人有這個問題:

linux下建立了乙個包含中文的檔案,拷貝到windows下面。

用記事本開啟看 ==> 漢字正確,換行的地方出現了黑方塊

用寫字板開啟看 ==> 換行正確,漢字亂碼

很有意思?可是如何解決?

如果就用windows系統自帶的記事本寫字板怎麼辦?看好了:

qt寫文字檔案換行符 Qt 文字檔案讀寫

文字檔案讀寫 二進位制檔案比較小巧,但是不是人可讀的格式。文字檔案是一種人可讀的格式的檔案,為了操作這種檔案,我們需要使用 qtextstream 類。qtextstream 和 qdatastream的使用類似,只不過它是操作純文字檔案的。還有一些文字格式,比如 xml html,雖然可以由 qt...

qt寫文字檔案換行符 Qt向文字檔案輸出換行

使用qtextstream向txt檔案輸出換行時,需要使用qiodevice text標誌。官方文件對qiodevice text的解釋 when reading,the end of line terminators are translated to n when writing,the end...

不同作業系統中文字檔案換行符的區別

文字檔案的邏輯結構屬於流式檔案,採用ascii編碼標準儲存字元。ascii標準使得只含有ascii字元的文字檔案可以在unix macintosh microsoft windows dos和其它作業系統之間自由互動,而其它格式的檔案是很難做到這一點的。但是,在這些作業系統中,換行符並不相同,處理非...