![](/img/trans.png)
[英]How to read bytes from file using std::ifstream to std::array?
[英]How to correctly read from already opened std::ifstream using a buffer
我实现了一个JSON解析器,并提供了一个operator>>
函数来解析std::ifstream
。 为了加快读取速度,我将16 KB复制到一个缓冲区中,让我的解析器从缓冲区中读取。 一个小的基准测试显示,这比直接使用std::ifstream::get
或std::ifstream::read
更快。
当我成功读取JSON值时,我想将所有不需要的字节从缓冲区“放回”到流中,因此后续调用operator>>
并使用相同的std::istream
继续解析第一个调用结束的位置。 我目前正在实施这样的“退回”:
is.clear();
is.seekg(start_position + static_cast<std::streamoff>(processed_chars));
is.clear();
因此, is
是输入文件流, start_position
是is.tellg()
的初始值,并且processed_chars
是解析器读取的字符数。
这适用于GCC和Clang与OSX和Linux,但MSVC 2015和MSVC 2017无法将输入流带入所需状态。
显然,我在这里做错了什么。 不同的编译器不应该表现得如此不同。 clear()
调用已经是试验和错误的结果,使代码与GCC / Clang一起运行。
(a)使用缓存从已打开的std::ifstream
读取和(b)能够在最后处理的字符之后(而不是在最后一个缓存的字符之后)恢复解析的正确方法是什么?
有没有更好的方法快速读取已经打开的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.