【问题标题】:What is the best way to seek past 2GiB in C?在 C 中寻找过去 2GiB 的最佳方法是什么?
【发布时间】:2015-12-21 03:16:51
【问题描述】:

在 C 中似乎有许多不同的搜索方式:

  • fseek()
  • fsetpos()
  • fseeko()
  • lseek()

而且很多似乎都有*64() 版本:

  • fseeko64()
  • lseek64()

更复杂的是,许多似乎需要宏定义(如_LARGEFILE64_SOURCE_GNU_SOURCE)才能使用或使用64 位版本。

在 Windows、Linux、Mac、BSD、Solaris 等平台上使用 ANSI C 保证 64 位 IO 的最简单方法是什么?从什么时候开始每个操作系统都支持它?

【问题讨论】:

标签: c 64-bit stdio


【解决方案1】:

代码作品至少需要采用以下限制之一::

  1. long 是 64 位+,然后使用 fseek()

  2. 仅查找代码之前由于fread(), fgets(), fscanf(), fgets() 而去过的位置,因此使用fgetpos()fsetpos()。如果文件是文本文件,这是最好的方法。

  3. 可以访问依赖于平台的 64 位搜索,例如 lseek64()

  4. 多个32位fseek()

  5. rewind()fgetc()/fread() 中使用效率极低的代码。

【讨论】:

  • 我不确定多个 32 位 fseek() 和 fgepos()/fsetpos() 可能也不起作用(很可能两种定位函数都使用相同的位置类型和最后调用相同的特定于操作系统的函数)。一个特定于操作系统的函数/系统调用是最好的选择,但显然不可移植。
  • @Alexey Frunze fgetpos()/fsetpos() 在 64+ 位系统和 32 位系统上同样有效。fseek() 在 32 位系统上通过 4G 更加脆弱。您提到的组合解决方案是最好的,尽可能使用标准调用。
【解决方案2】:

使用 ANSI C 保证 64 位 IO 的最简单方法是什么? Windows、Linux、Mac、BSD、Solaris 等

最简单的方法?将您的代码编译为 64 位可执行文件。确保使用正确的类型,例如size_t 不是 unsigned int - size_tsize_t。希望您已经超越了ANSI C,因为它通常指的是 C89,并且可能不支持 64 位架构。

正如 cmets 所暗示的,没有任何符合 C 标准的方法可以保证您可以轻松超过 2GB。但是,对于 64 位二进制文​​件,POSIX 兼容 IO(open()read()write() 等)都可以作为 POSIX IO 使用的size_t/ssize_t 是 64 位的。 POSIX 还指定了fseeko() and ftello(),它是 64 位兼容的。

从什么时候开始每个操作系统都支持它?

详情请见here。粗略地说,“完整”的 64 位支持大约可以追溯到以下时间:

  • 索拉里斯:1998
  • Linux:2003
  • Windows:2006
  • OS X:2007

【讨论】:

  • 标准 C 定义的 fseek() 函数将 offset 传递为 long,但取决于 data model(例如 Windows 使用 LLP64),long 可能不是 64-位;这就是 2GiB 限制的来源(LONG_MAX 必须至少为 (2^31)-1)。
  • @oopaewem 感谢您指出这一点,但 OP 确实要求最简单的方式。在这种情况下,您将返回到 Lưu Vĩnh Phúc 在他上面的评论中的链接(没有符合 C 标准的方式):stackoverflow.com/questions/30657968/…
  • 我看到了那个链接,我想我的 OP 有点误导。 ANSI CI 并不意味着我想使用专有的 ANSI C 而没有其他(可能依赖于平台的)库,我只是想说我不想使用任何 C99 或 C11 功能,因为微软仍然没有完整的 C99 编译器(他们也不打算这样做)。也就是说,C11 似乎也没有任何标准方法可以在 LLP64 数据模型上查找过去的 2GiB,所以这是一个有争议的问题。
  • @oopaewem POSIX 似乎是唯一明确解决 64 位问题的标准。 unix.org/whitepapers/64bit.html
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-30
  • 1970-01-01
  • 2019-05-16
  • 2010-12-16
  • 2011-04-04
  • 2013-02-15
相关资源
最近更新 更多