首页 > 解决方案 > 在溪流中跳回安全吗?(std::ifstream, std::ofstream)

问题描述

案例 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. 到目前为止,我的代码对我所做的一切都运行良好,我只是担心它可能会在某些未知情况下崩溃/崩溃

标签: c++iostream

解决方案


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

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

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

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


推荐阅读