天天看點

關于檔案流的操作

最近在學習socket程式設計,做了一個小項目,就是傳輸大檔案,具體的内容就是使用epoll LT模式,用戶端發送檔案到服務端,服務端再把收到的内容完整的寫入另一個檔案中。

測試過程中不知道為什麼傳輸完成之後服務端寫入的新檔案總是比用戶端傳來的檔案内容少了幾千個位元組,也有對伺服器程式進行驗證,伺服器确确實實有接收到這些檔案内容(少了的那幾千個位元組),也有确實有通過ofstream輸出檔案流輸出到指定的檔案中。

一直很納悶,找不到解決方案,後來找到了一篇博文說在操作檔案流時,當不再使用該檔案流的時候,一定要進行close操作,但是也沒有說明為什麼。然後我就着手去修改了一下程式,在用戶端關閉了的時候對ofstream進行close操作,發現問題真的解決了!

然後就去了解了一下為什麼需要這樣做,找到了以下答案:

在《C++ Primer》第五版8.1.3中有這樣一句話“每個輸出流都管理一個緩沖區,用來儲存程式讀寫的資料。例如,如果執行下面代碼‘ os << “please enter a value”; ’ 文本串可能會立即列印出來,但也有可能被作業系統儲存在緩沖區中,随後再列印。”

關于檔案流的操作

通過這段話其實也就明白了為什麼需要在操作檔案流之後對檔案流進行close操作了(但是其實也還得要了解一下重新整理緩沖區的操作!),對檔案流進行close會重新整理緩沖區(應該不是每個io流進行close都會進行重新整理緩沖區操作,因為沒有測試過是以不敢下結論,但是對ofstream進行close是會的,因為我測試過),當你沒有進行close操作的時候,此時緩沖區中還有一些資料未被輸出,如果程式突然中斷/異常退出,緩沖區中的資料沒有得到處理,是以就造成了資料丢失的情況!

當然,也可以在每次輸出操作之後手動重新整理緩沖區,這樣即使沒有close也不會丢失資料,但是這種習慣不好,而且這種操作也喪失了緩沖區機制帶來的好處之一(可以将程式的多個輸出操作合并成一個單一的系統級寫操作),是以還是要養成open與close成對出現的好習慣!