gpt4 book ai didi

c++ - 如何使用缓冲区正确读取已打开的 std::ifstream

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:42:24 24 4
gpt4 key购买 nike

背景

我实现了一个 JSON 解析器并提供了一个 operator>> 函数来解析 std::ifstream。为了加快读取速度,我将 16 KB 复制到一个缓冲区中,然后让我的解析器从缓冲区中读取。一个小型基准测试表明,这比直接使用 std::ifstream::getstd::ifstream::read 更快。​​

当前(错误?)实现

当我成功读取一个 JSON 值时,我想将所有不需要的字节从缓冲区“放回”到流中,以便随后使用相同的 std 调用 operator>>: :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);

关于c++ - 如何使用缓冲区正确读取已打开的 std::ifstream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44503211/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com