1. 程式人生 > >windows平臺下使用open,read等函式易錯點及與fread等區別

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 

count if there are fewer than count bytes left in the file or if the file was opened in text mode, in which case each carriage return–line feed (CR-LF) pair is replaced with a single linefeed character

由此我們可以知道為什麼返回值為9,但是buf2的值為什麼倒數第一位和第二位會相同,這個恐怕得通過反彙編看read內部的實現了。

小結:當移植linux程式碼到windows下事,要記得使用二進位制模式開啟和操作檔案,文字方式使用read函式很容易出現上述為題。如果一定要使用文字方式,就採用標準I/O庫函式吧,fopen,fread等。