为什么POSIX允许在现有文件结束(fseek)之外寻找只读模式

时间:2018-02-02 14:46:10

标签: c++ c posix

为什么寻找文件结尾可能有用?为什么POSIX允许在打开的文件中寻找只读的示例?

c ++:http://en.cppreference.com/w/c/io/fseek posix: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;
}

2 个答案:

答案 0 :(得分:6)

  

为什么寻找文件结尾可能有用?

一般是否有用取决于实施。 C和C ++没有指定这样的动作必须成功,尽管POSIX确实如你所知。但是,即使在非POSIX C中,

  

如果[{1}}]内发生读或写错误,则流的错误指示符为   设置并fseek失败

C2011 7.21.9.2/2)和

  

成功调用fseek函数会撤消对流fseek函数的任何影响,清除流的文件结束指示符

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

  

为什么POSIX允许在打开的只读文件中寻找示例?

建议您认为fseek或许应该失败,否则会将(只读)文件定位在无法读取数据的位置。但为什么要为此做一个特例呢?一个可以读取和写入的文件可以(根据POSIX)定位在其末尾,然后读取它与读取类似位置的只读文件没有特别的不同。

fseek的所有可搜索文件的行为保持一致比您似乎更欣赏它。

答案 1 :(得分:5)

如您所知,寻找超出可写文件的末尾,然后编写,扩展文件。我认为你的问题是,你不想扩展一个仅供阅读的文件,因为扩展是一种修改。

但只是寻找超出可写文件的末尾并不能扩展它 - 它正在寻找然后编写。寻求只设置读/写点。

因此,在读取时寻找超出文件末尾的设置读取点,这只是数据结构中的一个数字,所以我想没有人担心检查它的有效性。如果你寻找超出可读文件的末尾,然后尝试写,你会收到一个错误(&#34;文件没有打开写入&#34;),如果你寻找超出可读文件的末尾,然后阅读,你只需要获得EOF。在任何情况下,您都不会扩展或以其他方式更改文件。

(你可能也想知道,如果你在一个其他进程正在编写的可读文件的末尾之外寻找会发生什么,然后其他进程会更多地写入&#34;填写&#34;到目前为止你曾经寻求过,那么你试着读?这是一个有趣的问题。我怀疑它会起作用,但我还没有尝试过。)