【问题标题】:Is jumping back in streams safe? (std::ifstream, std::ofstream)在溪流中跳回安全吗? (std::ifstream, std::ofstream)
【发布时间】:2020-04-07 15:40:46
【问题描述】:

案例 A。我需要在 istream 中查找某些内容,然后可能会跳回重新开始。

案例 B。我需要写入 ostream,然后有时会跳回一些字符以覆盖内容。

以下代码是否安全? (即保证不会崩溃)

// Case A
std::ifstream Stream; // or std::istringstream Stream
// save position
auto initial_position = Stream.tellg();
// Read some characters
while ( ... ) { Stream.get(); ... }
// jump back
Stream.seekg( initial_position );
// Case B
std::ofstream Stream; // or std::ostringstream Stream
// save position
auto initial_position = Stream.tellp();
// Write some characters
while ( ... ) { Stream.put(); ... }
// jump back
Stream.seekp( initial_position );

注意事项:

  1. 我猜如果我们跳回到已经“从内存中丢弃”(对于 istream)或刷新到磁盘(对于 ostream)的位置,性能可能会受到影响,但我想这无论如何都是罕见的情况。有没有办法防止最坏的情况发生?

  2. 我不想(而且基本上不能)使用中间字符串来执行读取或写入操作。

  3. 到目前为止,我的代码运行良好,我只是担心它可能会在某些未知情况下崩溃/崩溃

【问题讨论】:

  • 取决于流。有些流没有内存。例如,您将一个字节写入电线,它就消失了。您无法将其回调,并且在设备运行几年后,存储通过该线路发送的所有数据可能会非常昂贵。..
  • @user4581301 这就是为什么我专门要求提到的 std::iostreams 。如果给出了 seekg 和 seekp,可以认为可以使用它们。
  • 我必须去标准潜水看看是否有保证,但是如果你不能在实际前面的文件流中查找,我有很多代码将无法工作一份文件。请注意,在 Unix 中,文件流可以表示一个串行端口,而最简单的串行端口只是一根电线。
  • 狩猎愉快。希望你不必潜入串口,那里的水一定很糟糕。

标签: c++ iostream


【解决方案1】:

它被称为流是有原因的——你只能读或写一次。就像“没有人会两次踏入同一条河流,因为它不是同一条河流,他也不是同一个人”。 (将“河流”替换为“溪流”)。

文件支持的流确实提供随机访问,但这更像是一个例外。此外,文件可能在您阅读时被截断和/或重写,因此您可能无法在刚刚阅读的文件流中向后或向前搜索。

最实用的解析算法只会按顺序检查输入的每个字节一次 - 这使得它们适用于任何流,例如文件、管道、套接字。您可能希望以这种方式实现解析。

当它们可以来回寻找输入时,还有其他最有效的解析算法。对于这些算法,首选方法是将整个文件或文件的特定部分映射到内存中。

【讨论】:

  • 谢谢。非常好的提示和风格!我喜欢“你可能喜欢...”实际上很容易提取我需要的部分,似乎我只是在那里有一个心理障碍......
  • 其实挺难的,因为不匹配的部分我得重用。我的阻止是合理的。
  • 仍然得出结论,尽管文档中没有明确的警告,但返回并不安全。
猜你喜欢
  • 2012-10-12
  • 1970-01-01
  • 1970-01-01
  • 2020-11-05
  • 1970-01-01
  • 2011-10-27
  • 2023-03-04
  • 1970-01-01
  • 2017-12-23
相关资源
最近更新 更多