【问题标题】:Why POSIX allows seeking beyond the existing end of file (fseek) for read only mode为什么 POSIX 允许在现有文件结尾 (fseek) 之外寻找只读模式
【发布时间】:2018-07-31 06:27:26
【问题描述】:

为什么在文件末尾查找会很有用?为什么 POSIX 允许在只读打开的文件中查找示例?

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

我在 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;
}

【问题讨论】:

  • 您的问题和代码似乎是关于 C++ 的,而您的链接是指向 C 资源的。 C 和 C++ 是不同的语言;你应该选择一个。
  • fseek() 的更正确的 POSIX 链接是 pubs.opengroup.org/onlinepubs/9699919799/functions/fseek.html
  • 可能是历史先例的结合(Unix 允许),没有特殊理由禁止它。
  • @DavidBowling C 和 C++ 是不同的语言;你应该选择一个。在这种情况下,-C standard IO-C++ 几乎遵循 C。尽管在这种情况下,我认为这并不重要 - 我认为 为什么 i> 要么完全不可知,要么基于意见。
  • @AndrewHenle -- 要点。

标签: c++ c posix


【解决方案1】:

为什么在文件末尾查找会很有用?

它是否有用一般取决于实现。 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】:

    如您所知,在可写文件的末尾之外寻找,然后写入,扩展文件。我认为您的问题是您不想扩展仅打开以供阅读的文件,因为扩展是一种修改。

    但是仅仅在可写文件的末尾寻找并不会扩展它——它是在寻找然后写入。寻找只是设置读/写点。

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

    (您可能还想知道,如果您在某个其他进程正在写入的可读文件的末尾之外寻找会发生什么,然后其他进程会写入更多内容以“填充”到您寻找的点,并且那么你尝试阅读?这是一个有趣的问题。我怀疑它会起作用,但我还没有尝试过。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-27
      • 2015-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多