最近我偶然發現一篇文章:How to read an entire file into memory in C++,其中描述了讀取文件的不同技術。每種方法都評論其效率或與未定義行爲相關的風險。 在列表下面的實例中,呈現:閱讀文件和未定義的行爲
// Bad code; undefined behaviour
in.seekg(0, std::ios_base::end);
這基本上在這個或類似的形式經常被用來實際讀取文件大小。 在後提出的推理,總之是,在C standard (N1570) §7.21.3
它指出:
設置文件位置指示器到檔案結尾,與 FSEEK(文件,0,SEEK_END),對於二進制流 (由於可能結尾空字符)或任何具有 狀態相關編碼的流沒有明確的行爲,該編碼在初始 移位狀態中並未確實結束。
哪個footnote 268
爲:
的文件不必開始也不在初始移位狀態
結束爲了確認上述用於C++ 11有一個附加的參考C++ standard draft (N3242) 27.9.1.1
其中規定:
對讀寫控制序列的限制 basic_filebuf類的對象與用標準C庫FILE讀寫 的對象相同。
凡basic_filebuf
根據cppreference是實施爲basic_ifstream
(內部緩衝器)的一部分。表明ifstream
實施應該也承擔着表示的行爲。
從我從描述和我設法挖掘的內容中瞭解到的情況來看,這個問題主要與面向廣泛的流有關,這些流可能不會以initial shift state
結尾。
對我而言,由於文件大小計算的流行用法,這似乎不是典型情況。這個話題對我來說還不是很清楚。因此,以下問題:
- 究竟是
initial state shift
?我認爲它不能與數據集羣相關。更多的是多字節字符編碼,但這種方式不會僅限於非二進制流? - 實際上,我們處理
wide-
和narrow-oriented
流嗎?我知道:"A newly opened stream has no orientation."
和方向是決定在第一個I/O調用流。但是在實踐中,假設有任何依賴於流類型,系統,語言環境或其他的默認值? - 如果還沒有回答或表示,那麼什麼時候會發生這種未定義的行爲的實際例子?從某種意義上說,可以複製它。
你是對的我也看到了。這會使獲取的大小不正確。結論仍然是:'你可以用二進制模式獲得ftell()的字符數......但是你不能用fseek(p_file,0,SEEK_END)來搜索文件的結尾。「此外,」一些平臺將文件存儲爲固定大小的記錄「聲明 - 您是否具有哪些平臺的知識?作者使用'gcount'提出的解決方案看起來有效。然而,我更感興趣的是在實踐中「尋求到最終獲取大小」的方法可能會失敗。 – Dusteh
@Dusteh在答案中發佈了一些額外的信息。這就是說,我真的不知道如何在我可以使用的常用操作系統上重新制作「面向記錄的文件訪問」。 –