代码之家  ›  专栏  ›  技术社区  ›  leanid.chaika

为什么POSIX允许在现有文件结尾(fseek)之外搜索只读模式

  •  2
  • leanid.chaika  · 技术社区  · 6 年前

    为什么在文件末尾搜索是有用的?为什么POSIX允许在以只读方式打开的文件中查找类似的示例?

    c++: http://en.cppreference.com/w/c/io/fseek posix: https://www.unix.com/man-page/posix/3P/fseek/

    下一个代码I在MinGW-64w上测试

    #include <cassert>
    #include <cstdio>
    #include <cstring>
    
    int main() {
      std::FILE* f = std::fopen("tmp_file.txt", "wb");
      auto result = std::fwrite("1", 1, 1, f);
      assert(result == 1);
      result = std::fclose(f);
      assert(result == 0);
    
      f = std::fopen("tmp_file.txt", "rb");  // READ ONLY binary mode
      result = std::fseek(f, 100500, SEEK_SET);
      assert(result == 0);  // WHY I can seek to not existing position in file?
                            // opended in READ_ONLY mode?
      char buff[100500] = {0};
      result = std::fread(&buff, sizeof(buff), 1, f);
      printf("result = %zu, errno: %s ferror(f): %d feof(f): %d", result,
             std::strerror(errno), std::ferror(f), std::feof(f) != 0);
    
      return result;
    }
    
    2 回复  |  直到 6 年前
        1
  •  6
  •   John Bollinger    6 年前

    为什么在文件末尾搜索是有用的?

    是否有用 一般来说 取决于实施情况。C和C++并没有指定这样的操作必须成功,尽管POSIX确实如此,正如您所知。然而,即使在非POSIX C中,

    如果发生读或写错误[在 fseek ],流的错误指示器为 设置和 fseek公司 失败

    ( C2011 7.21.9.2/2 ),和

    成功调用 fseek公司 函数撤消 ungetc 函数,清除流的文件结束指示符

    ( C2011 7.21.9.2/5 ). 这些副作用可能是可取的,即使 fseek公司 使文件处于奇怪(但有效)状态。尽管如此,你的问题

    为什么POSIX允许在以只读方式打开的文件中查找类似的示例?

    表明你可能认为 fseek公司 如果它将(只读)文件放置在无法读取数据的位置,则应该失败。但为什么要对此进行特殊处理呢?可以(根据POSIX)将一个读写都打开的文件定位在其末尾之后,然后读取它与读取一个位置类似的只读文件没有什么特别的不同。

    制作 fseek公司 的行为在所有可查找的文件中保持一致,这比您所欣赏的更有价值。

        2
  •  5
  •   Steve Summit    6 年前

    如您所知,在可写文件的结尾之外查找,然后写入,会扩展文件。我想你的问题是,你不想扩展一个只开放阅读的文件,因为扩展是一种修改。

    但是仅仅在一个可写文件的末尾之外寻找并不能扩展它--它正在寻找 然后写 . 查找只设置读/写点。

    因此,在读取时查找文件末尾以外的内容会设置读取点,这只是数据结构中的一个数字,所以我想没有人担心检查它的有效性。如果您在可读文件的结尾之外进行查找,然后尝试写入,则会出现错误(“文件未打开以进行写入”),如果您在可读文件的结尾之外进行查找,然后进行读取,则只会得到EOF。在这两种情况下,您都不会扩展或更改文件。

    (您可能还想知道,如果您在某个其他进程正在写入的可读文件的结尾之外进行查找,然后该其他进程再写入一些内容以“填充”到您想要的位置,会发生什么情况,以及 然后 你想读书吗?这是一个有趣的问题。我怀疑它会起作用,但我还没有试过。)