C++ 如何使用缓冲区正确读取已打开的std::ifstream 背景
我实现了一个JSON解析器,并提供了一个C++ 如何使用缓冲区正确读取已打开的std::ifstream 背景,c++,caching,ifstream,C++,Caching,Ifstream,我实现了一个JSON解析器,并提供了一个操作符>函数来解析std::ifstream。为了加快读取速度,我将16KB复制到缓冲区中,让解析器从缓冲区中读取。一个小型基准测试表明,这比直接使用std::ifstream::get或std::ifstream::read更快 当前(错误?)实现 当我成功读取一个JSON值时,我想将所有不必要的字节从缓冲区“放回”到流中,这样后续调用operator>,使用相同的std::istream在第一次调用结束的地方继续解析。我目前实施的“放回”方式如下: i
操作符>
函数来解析std::ifstream
。为了加快读取速度,我将16KB复制到缓冲区中,让解析器从缓冲区中读取。一个小型基准测试表明,这比直接使用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.clear();
is.seekg(起始位置+静态施法(加工字符));
is.clear();
因此,is
是输入文件流,start\u position
是is.tellg()
的初始值,processed\u chars
是解析器读取的字符数
这适用于GCC和Clang,适用于OSX和Linux,但MSVC 2015和MSVC 2017无法将输入流带入所需状态
我的问题
clear()
调用已经是使用GCC/Clang运行代码的尝试和错误的结果std::ifstream
读取,以及(b)能够在最后处理的字符之后(而不是在最后缓存的字符之后)恢复解析,正确的方法是什么std::ifstream
?如上所述,删除缓存会使解析器速度变慢(对于这个天真的问题和可怕的实现,我深表歉意!我没有找到一个关于这个问题的答案,这个答案可以处理已经打开的
std::ifstream
,或者可以“放回”已经缓存的字符。)如果以文本模式打开文件流,这是无效的:
is.seekg(start_position + static_cast<std::streamoff>(processed_chars));
嗯,你真的需要它在MSVC下编译吗?您甚至可以从linux/Mac计算机上使用GCC/Clang创建windows可执行文件,对吗?您可以通过编写自定义的
::std::streambuf
实现来创建自定义缓冲文件流。@niceman最后,我只提供了一个应该到处编译的头,请参阅@VTT我可以将此自定义缓冲区与传递的std::ifstream
对象一起使用吗?而将字符从缓冲区“放回”流会是什么样子呢?通常,在创建它时,您会将streambuf
实例指针传递到istream
,而根本不需要使用ifstream
。只要您在streambuf
实现中提供相应的重载,流将处理“放回”和其他操作。
// is is the istream
auto tg = is.tellg();
is.read(buffer, BUFFER_SIZE);
// process...
is.seekg(tg); // valid
is.ignore(processed_chars);