C++ 如何使用缓冲区正确读取已打开的std::ifstream 背景

C++ 如何使用缓冲区正确读取已打开的std::ifstream 背景,c++,caching,ifstream,C++,Caching,Ifstream,我实现了一个JSON解析器,并提供了一个操作符>函数来解析std::ifstream。为了加快读取速度,我将16KB复制到缓冲区中,让解析器从缓冲区中读取。一个小型基准测试表明,这比直接使用std::ifstream::get或std::ifstream::read更快 当前(错误?)实现 当我成功读取一个JSON值时,我想将所有不必要的字节从缓冲区“放回”到流中,这样后续调用operator>,使用相同的std::istream在第一次调用结束的地方继续解析。我目前实施的“放回”方式如下: i

我实现了一个JSON解析器,并提供了一个
操作符>
函数来解析
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运行代码的尝试和错误的结果

  • (a)使用缓存从已打开的
    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);