【问题标题】:fseek and fwrite past EOFfseek 和 fwrite 过去 EOF
【发布时间】:2020-08-12 19:03:11
【问题描述】:

让我们首先假设我有一个由 5 个整数组成的 20 字节二进制文件。现在让我们说我试图:

fseek(fp, 2*sizeof(int), SEEK_END)

我试着打电话:

fwrite(&i, sizeof(int), 1, fp);

这可能吗?

如果可能的话,新的二进制文件的大小是 32 还是只是 24?如果是32,那么20到27位的二进制文件内容是什么?

【问题讨论】:

  • 建议 fseek (fp, 7*sizeof(int), SEEK_BEGIN) 避免“二进制流不需要有意义地支持 wherece 值为 SEEK_END 的 fseek 调用。”

标签: c file file-io binary


【解决方案1】:

根据this

  • 允许库实现无意义地支持SEEK_END因此,使用它的代码没有真正的标准可移植性)。

还有here

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

在我的测试系统上,seeking 过去的SEEK_END 用空字节填充文件的其余部分,直到新的文件指针。

【讨论】:

  • 这是否意味着不能调用 fseek(fp, 2*sizeof(int), SEEK_END) 但可以调用 fseek(fp, 7*sizeof(int), SEEK_SET)。如果我尝试在该位置调用 fwrite 新文件大小将只是 24,我真的不明白稀疏文件的含义。
  • @Janjan 要看系统是否支持,所以代码不会真正的可移植。
  • @Janjan 一个 sparse file 只会将包含数据的块写入磁盘(大部分是 16kB 块)并用 \0“填充”其余部分。例如,如果您有一个开头为 100 字节、大约 1GB 为 100 字节的文件,那么您将拥有一个 1GB 的文件,该文件在磁盘上仅占用 32kB(不在磁盘上的部分全为零)。
  • 如果我尝试使用 fread 访问此文件,我必须使用与调用 fwrite 相同的指针位置吗?
  • @Janjan 是的,操作系统会处理所有这些(从代码来看,数据是在磁盘上还是虚拟零没有区别)。如果您稍后以大约 500MB 的大小写入,则会将一个新的 16kB 块(或 2 个)写入磁盘。唯一的缺点是这些块不会在磁盘上“按顺序”排列,如果稍后填充所有这些空块(就像碎片整理文件一样),读取时间可能会稍长。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-12
  • 2017-07-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多