绕过 ftell/fseek 的 2GB 限制






4.90/5 (12投票s)
2005 年 1 月 29 日
2分钟阅读

93596
关于如何实现 _fseeki64 和 _ftelli64 的说明。
引言
最近,我正在完成一个 Linux 程序到 Windows 的移植。它被称为 mpgtx,是一个命令行 MPEG 编辑程序。移植很容易,因为它没有使用很多 Linux 特定的函数(而且已经有人完成了部分移植),但我确实遇到了一个大问题:它会在任何长的 MPEG-2 剪辑上失败。我很快意识到这是因为 fseek
/ftell
函数使用数据类型 long
作为文件偏移量,这在大多数系统上是一个 32 位有符号整数。因此,这些函数在大于 2048 兆字节的文件上不起作用。然后我搜索了有关解决此问题的信息,我发现的唯一信息是关于 Linux 专用的函数 (fseeko
/ftello
) 或非缓冲函数 (_lseeki64
)。我不想使用 Cygwin,而且我真的不想将所有 fopen
/fread
/fseek
/etc... 函数调用转换为 _open
/_read
/_lseeki64
/etc... 并且仍然保持与 Linux 的代码兼容性,所以我必须找到另一种方法。我以为因为有一个 _lseeki64
函数,可能有一个 fseeki64
函数,但在帮助系统中没有提到该函数,而且在 Google 上搜索时几乎没有列出任何内容。但是,Google 确实找到了一页,上面说 "crt/src" 中有一个名为 "fseeki64.c" 的文件。果然,fseeki64.c 和 ftelli64.c 文件都存在于我的 "Microsoft Visual Studio .NET 2003\Vc7\crt\src" 文件夹中。不幸的是,stdio.h 中没有提到这两个函数,因此使用这些函数需要额外的工作...
使用代码
首先,您必须将以下导入添加到您的代码中
extern "C" int __cdecl _fseeki64(FILE *, __int64, int); extern "C" __int64 __cdecl _ftelli64(FILE *);
请注意,它们使用 __in64
作为文件偏移量的数据类型,而不是 long
。
接下来,分别将所有对 fseek
和 ftell
的调用替换为 _fseeki64
和 _ftelli64
。最后,将用于保存文件偏移量的所有变量从 long
更改为 __int64
。就是这样;现在您应该没问题了!
关注点
有人知道为什么 _fseeki64
和 _ftelli64
完全、神秘地没有文档记录吗?