C++ 在小溪里跳回去安全吗?(std::ifstream,std::ofstream)

C++ 在小溪里跳回去安全吗?(std::ifstream,std::ofstream),c++,iostream,C++,Iostream,案例A:我需要在一个istream中寻找一些东西,然后可能跳回去重新开始 案例B:我需要向一个ostream写入数据,然后有时跳回一些字符以覆盖内容 以下代码是否安全?(即保证不发生碰撞) 注: 我想,如果我们跳回一个已经被“从内存中丢弃”(对于istream)或刷新到磁盘(对于ostream)的位置,性能可能会受到影响,但我想这是一种罕见的情况。有没有办法防止最坏的情况发生 我不想(基本上也不能)使用中间字符串来进行读写操作 到目前为止,我的代码一直运行良好,我只是担心它可能会在某些未知情况下

案例A:我需要在一个istream中寻找一些东西,然后可能跳回去重新开始

案例B:我需要向一个ostream写入数据,然后有时跳回一些字符以覆盖内容

以下代码是否安全?(即保证不发生碰撞)

注:

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

  • 我不想(基本上也不能)使用中间字符串来进行读写操作

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


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

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

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


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

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

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

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


    还有其他一些解析算法,当它们能够来回搜索输入时,效率最高。对于这些算法,首选的方法是将整个文件或其特定部分映射到内存。

    取决于流。有些流没有内存。例如,当你把一个字节写到一条线上时,它就消失了。你不能回电,在设备运行了几年之后,存储通过该线路发送的所有数据可能会非常昂贵。@user4581301这就是为什么我特别要求使用提到的std::iostreams。如果给出了seekg和seekp,人们可能会认为使用它们是可以的。我必须去标准潜水,看看是否有保证,但是如果你不能在一个文件流中查找回一个文件,我有很多代码将无法工作。请注意,在Unix中,文件流可以表示一个串行端口,而串行端口最简单的形式就是一个wire.Happy hunting。希望你不必在串行端口潜水,那里的水一定很糟糕。这取决于水流。有些流没有内存。例如,当你把一个字节写到一条线上时,它就消失了。你不能回电,在设备运行了几年之后,存储通过该线路发送的所有数据可能会非常昂贵。@user4581301这就是为什么我特别要求使用提到的std::iostreams。如果给出了seekg和seekp,人们可能会认为使用它们是可以的。我必须去标准潜水,看看是否有保证,但是如果你不能在一个文件流中查找回一个文件,我有很多代码将无法工作。请注意,在Unix中,文件流可以表示一个串行端口,而串行端口最简单的形式就是一个wire.Happy hunting。希望你不用在串口潜水,那里的水一定很糟糕。谢谢。非常好的提示和风格!我喜欢“你可能喜欢…”这句话,其实提取我需要的零件很容易,似乎我只是有一个心理障碍…实际上很难,因为如果零件不匹配,我必须重复使用。我的阻止是合理的。尽管文件中没有明确的警告,但仍然得出结论,回去是不安全的。谢谢。非常好的提示和风格!我喜欢“你可能喜欢…”这句话,其实提取我需要的零件很容易,似乎我只是有一个心理障碍…实际上很难,因为如果零件不匹配,我必须重复使用。我的阻止是合理的。尽管文件中没有明确的警告,但我仍然得出结论,回去是不安全的。
    // 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 );