【问题标题】:Accessing Large Files In C在 C 中访问大文件
【发布时间】:2012-01-16 02:48:39
【问题描述】:

我需要使用 C 访问一个大于 2gb 的文件。在一次程序运行期间,将从文件中读取可变数量的字节并保存下一个位置的位置。在程序的下一次运行期间,将读取文件位置并从该位置开始读取多个字节。

复杂之处在于,有时可能会通过将文件复制到新文件来“压缩”文件,减去已读取的任何字节(我认为复制是唯一的方法)。这样删除的字节数也会被保存。

我需要知道文件从原始开始的当前位置,以便与另一个文件同步。这应该很容易,因为它只是 (current_offset + deleted_bytes)。

不容易的原因是 fseek 只使用 long int 索引,将文件限制为 2gb,而 fsetpos 使用 fpos_t 结构作为位置索引,它不是数字,不能来回转换为一。我不知道有什么方法可以使用 long long int 索引进行文件定位,这将是理想的解决方案。

我该怎么办?

【问题讨论】:

  • 哪个平台? ftello()fseeko() 可能是一个选项。
  • ftello 和 fseeko 将与 POSIX.1 兼容,但 >2GB 也是文件系统相关问题。

标签: c windows visual-studio


【解决方案1】:

在 Windows 上,您可以使用 _lseeki64() 进行 64 位搜索。

为了与 linux 兼容,您还可以在编译时添加 -D_FILE_OFFSET_BITS=64,然后在您的某个标头中执行此操作:

#ifdef __MINGW32__ // or whatever you use to find out you're compiling on windows
#define lseek _lseeki64
#endif

然后像往常一样在任何地方使用lseek()。这是可行的,因为 windows 忽略了 _FILE_OFFSET_BITS 标志,并且 linux 不会看到 lseek 的重新定义。

如果您更喜欢FILE* 版本,还有_fseeki64(),还有等效的64 位tell()ftell() 函数(_telli64()_ftelli64())。

【讨论】:

  • 我认为这就是我所需要的。谢谢!
  • 不客气。关于使其可移植的另一个注意事项 - 我不记得 Windows 是否声明了off_t,所以你可能还需要在 Windows 上使用#define off_t __int64(这样你就可以向the lseek() interface 编写代码)。但我不能 100% 确定 - 也许 off_t 现在在某处定义。
  • @TimothyJones 如何在 Windows 中设置 _file_offset_bits?我在 32 位 Windows7 机器上从 Visual Studio 2008 编译。我试图按照这个例子coding.derkeiler.com/Archive/C_CPP/comp.lang.c/2006-12/… 但我收到以下错误 c2371: 'off_t' : redefinition;不同的基本类型
  • 没有等效项 - _FILE_OFFSET_BITS 在 Windows 上被忽略。您需要使用所需功能的 64 位版本。我相信Windows上的off_tis a long integer(即only 32 bits)。出现您的错误是因为该代码尝试重新输入定义 off_t。您可以使用我上面评论中的建议来解决这个问题-#define off_t __int64(但仅限于 Windows,当然)。
【解决方案2】:

添加编译标志-D_FILE_OFFSET_BITS=64,使fopenfseekoff_t等变为64位,可用于处理大于2 GB的文件。请参阅Large File Support in Linux 了解更多信息。

【讨论】:

  • 优秀的解决方案。不幸的是,我应该提到我正在使用 Windows 和 Visual Studio。
  • 我想我没有想到编译器特定的解决方案。我搜索了 Visual Studio 文档,发现在 Windows 中使用 64 位索引的 SetFilePointer。我希望让我的代码比这更可移植。也许我需要学习如何使用#ifdef 来检测它所在的平台并拥有一个完整的编译器指令列表或其他东西。
  • 我会留下答案,以防它对 Linux/OS X 用户有用。 Makefile 将允许您按平台确定编译选项。
猜你喜欢
  • 1970-01-01
  • 2021-05-28
  • 2017-05-07
  • 2016-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-28
相关资源
最近更新 更多