簡體   English   中英

如何使用緩沖區正確讀取已打開的std :: ifstream

[英]How to correctly read from already opened std::ifstream using a buffer

背景

我實現了一個JSON解析器,並提供了一個operator>>函數來解析std::ifstream 為了加快讀取速度,我將16 KB復制到一個緩沖區中,讓我的解析器從緩沖區中讀取。 一個小的基准測試顯示,這比直接使用std::ifstream::getstd::ifstream::read更快。

當前(錯誤?)實施

當我成功讀取JSON值時,我想將所有不需要的字節從緩沖區“放回”到流中,因此后續調用operator>>並使用相同的std::istream繼續解析第一個調用結束的位置。 我目前正在實施這樣的“退回”:

is.clear();
is.seekg(start_position + static_cast<std::streamoff>(processed_chars));
is.clear();

因此, is是輸入文件流, start_positionis.tellg()的初始值,並且processed_chars是解析器讀取的字符數。

這適用於GCC和Clang與OSX和Linux,但MSVC 2015和MSVC 2017無法將輸入流帶入所需狀態。

我的問題

  1. 顯然,我在這里做錯了什么。 不同的編譯器不應該表現得如此不同。 clear()調用已經是試驗和錯誤的結果,使代碼與GCC / Clang一起運行。

  2. (a)使用緩存從已打開的std::ifstream讀取和(b)能夠在最后處理的字符之后(而不是在最后一個緩存的字符之后)恢復解析的正確方法是什么?

  3. 有沒有更好的方法快速讀取已經打開的std::ifstream 如上所述,刪除緩存會使解析器變慢。

(對於天真的問題和可怕的實現道歉!我沒有找到答案,處理已經打開的std::ifstream或者可以“放回”已經緩存的字符。)

如果以文本模式打開文件流,則無效:

is.seekg(start_position + static_cast<std::streamoff>(processed_chars));

...因為根據標准, seekg / tellg與處理的字符數量沒有直接關系(這實際上與操作系統有關)。

以下是可能的選項(無法提供您在問題中提供的更多詳細信息):

  • 使用putback來放回你讀過但未使用的字符;
  • 使用tellg來獲得正確的位置。

這樣的事情可能是:

// is is the istream
auto tg = is.tellg();
is.read(buffer, BUFFER_SIZE);
 // process...
is.seekg(tg); // valid
is.ignore(processed_chars);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM