【问题标题】:Behaviour of fseek with SEEK_END and a positive offset?带有 SEEK_END 和正偏移的 fseek 的行为?
【发布时间】:2019-04-17 18:43:15
【问题描述】:

假设我们有一个包含字符串“0123456789”的文件“x”。

我们打开文件,有一个文件描述符fd

我们可以通过read(fd, some_buffer, 5) 将文件中的 5 个值读入缓冲区。

同样,我们可以使用 fseek 将指针移动到文件中的各个条目。

我的问题是,当我们使用带有正偏移量的 SEEK_END 时,fseek 的行为是什么?这种行为是未定义的,还是绕到文件内容的前面?

如果我们做fseek(fd, 5, SEEK_END),指针现在会指向哪里?

【问题讨论】:

  • 就C规范而言,二进制文件不需要支持SEEK_END,文本文件也绝对不支持。有一件事是肯定的:带有正偏移量的 SEEK_END 不会环绕到文件的前面。它要么放大文件,要么失败。

标签: c fseek


【解决方案1】:

我的问题是,当我们使用SEEK_END 时,fseek 的行为是什么? 有正偏移?这种行为是未定义的,还是包装 绕到文件内容的前面?

如果流是 text 流,那么就 C 语言而言,行为是未定义的,因为标准规定:

对于文本流,offset 应为零,或offset 应为 先前成功调用 ftell 函数返回的值 在与同一文件关联的流上,whence 应为 SEEK_SET.

(C2011, 7.21.9.2/4)。没有为非零偏移量和SEEK_END 的组合定义任何行为。

对于二进制流,

新位置,以从开头开始的字符为单位 文件,通过将偏移量添加到指定的位置获得 whence

(C2011, 7.21.9.2/3),所以不,它绝对不会环绕。标准接着说

二进制流不需要有意义地支持 fseek 调用 SEEK_END的值从何而来

,所以你描述的这样的调用可能(定义地)失败,返回一个错误代码。但是,如果它确实成功了——并且在某些实现中,它可以预期对某些流这样做——那么它会导致文件位置超过文件的末尾。尝试在这样的位置读取应该具有与该位置在 EOF 相同的结果。写入尝试的行为取决于文件的打开模式(对以追加模式打开的流的所有写入都转到文件的当前末尾)和实现。

例如,在 POSIX 系统上,系统的 C 实现被指定为允许将与常规文件关联的流定位到文件末尾之后,并且在这样的位置成功写入的行为就像值 0 的字节被写入与文件前一个结尾之间的所有位置。此外,POSIX 在实践中并没有区分文本流和二进制流。

【讨论】:

    【解决方案2】:

    为什么不阅读documentation

    POSIX 允许在现有文件末尾之外进行查找。如果输出是 在此搜索之后执行,从间隙中读取的任何内容都将返回零 字节。在文件系统支持的情况下,这会创建一个稀疏文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-29
      • 1970-01-01
      • 2013-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多