windows平臺下使用open,read等函式易錯點及與fread等區別
一般情況下,我們只在linux平臺下使用open,read等檔案I/O函式,《UNIX環境高階程式設計第二版》中介紹他們是POSIX.1標準的組成部分。
筆者偶然的機會將Linux下的程式移植到windows平臺下,卻發現這些函式同樣可以使用,但需要加入標頭檔案io.h ,同時遇到了下面的一個問題。
檔案src_file如下:
測試程式碼如下:(buf1,buf2均初始化為0)
fsrc = fopen(src_file,"r+");
fsrc2 = open(src_file,O_RDONLY);
int rwsize = fread(buf1,1,10,fsrc);
int rwsize2 = read(fsrc2,buf2,10);
分別用read和fread方式開啟,兩者的結果不一樣。rwsize = 10,rwsize2 =9.
buf1[0]='0A',後面是123456789
buf2[0]='0A',後面是123456788
buf1的結果容易理解,因為windows對回車換行的處理原因,再寫入‘0a’之前都會加入‘0d’,同理在讀取時也會自動忽略‘0d’,所以跳過最初的‘0d’後再讀取了10個位元組的內容,返回值也是10.
buf2的結果則讓人困惑,它也沒有讀取‘0d’,但是返回值只有9,說明計數的時候又算了‘0d’的個數,而且最後的8怎麼出現的也未可知。經過嘗試,發現最後一位總是和倒數第二位相同。
後來查閱了MSDN上的官方資料,發現了open函式的以下說明。
我們在學習unix程式設計的時候,open是沒有這兩個選項的,因為在linux下開啟的都是位元組流。但是在windows環境下就不同了,因為文字方式和二進位制方式對待0d,0a操作是不同的,二進位制方式不會省略0d.
如果通過fsrc2 = open(src_file,O_RDONLY|_O_BINARY)方式開啟fsrc,則會得到rwsize2=10 ,buf[0]='0d',buf[1]='0a',後面為12345678.這個結果就容易理解了。
對於一開始得到的123456788,msdn上的read函式有以下說明,
_read returns the number of bytes read, which might be less than
由此我們可以知道為什麼返回值為9,但是buf2的值為什麼倒數第一位和第二位會相同,這個恐怕得通過反彙編看read內部的實現了。
小結:當移植linux程式碼到windows下事,要記得使用二進位制模式開啟和操作檔案,文字方式使用read函式很容易出現上述為題。如果一定要使用文字方式,就採用標準I/O庫函式吧,fopen,fread等。