答案 0 :(得分:10)
事实证明,各种标准定义了很多功能:
fseek
/ ftell
它由ANSI标准库定义。几乎无处不在。它保证只能使用32位整数,但不需要(意味着您可以获得开箱即用的大文件支持)。
fseeko
/ ftello
这是由POSIX标准定义的。在许多平台上,根据_FILE_OFFSET_BITS
的值,off_t
将off64_t
定义为fseeko
,将fseeko64
定义为_FILE_OFFSET_BITS=64
。{ / p>
fseeko64
/ ftello64
这是fseeko
和ftello
的64位等价物。我无法在任何标准中找到相关信息。
Cygwin不一致
虽然它符合POSIX,但无论我在Cygwin下定义什么,我都无法编译fseeko
,除非我使用--std=gnu++11
这显然是无稽之谈,因为它是POSIX而不是GNU的一部分延期。什么给出了什么?根据{{3}}:
64位文件访问是很自然的 Cygwin的文件访问类型。 off_t是8个字节。没有foo64 出于这个原因的功能。只需使用fopen和朋友就可以获得64分 位文件免费访问。
对于POSIX平台上的cygwin,这意味着#ifdef
。
_fseeki64
/ _ftelli64
这些是由Microsoft Visual C ++定义的,并且与其编译器一起使用。显然它不支持上面列表中的任何其他内容(fseek
除外),因此您需要#ifdef
s。
编辑:我实际上建议不要使用它们和this discussion。我经历了以下经历:
wfopen
二进制模式的文件fwrite
10个字节值得它_ftelli64
职位看起来这是非常糟糕的。
lseek
和lseek64
由POSIX定义,这些将与从open()
而不是unistd.h
结构使用FILE*
打开的整数文件描述符一起使用。这些与Windows不兼容。同样,他们使用off_t
数据类型。
_lseek
,_lseeki64
这相当于Windows lseek
/ lseek64
。奇怪的是,_lseeki64
不使用off_t
而是使用__int64
,因此您知道它将适用于大文件。整齐。
fsetpos
/ fgetpos
虽然这些实际上非常便携,但它们几乎无法使用,因为它们在不透明结构而不是整数偏移上运行,这意味着您可以添加或减去它们,甚至导航到通过除以外的任何方式获得的文件中的某个位置fgetpos
。
因此,为了使您的程序可移植,取决于平台,您应该使用:
fseeko
(POSIX)+在POSIX上定义_FILE_OFFSET_BITS=64
fseek
用于Cygwin和默认实现_lseeki64
- 或者,如果您设法绕过它 - _fseeki64
。使用_ftelli64
的示例:
int64_t portable_ftell(FILE *a)
{
#ifdef __CYGWIN__
return ftell(a);
#elif defined (_WIN32)
return _ftelli64(a);
#else
return ftello(a);
#endif
}
实际上,不是检查对我来说总是看起来很脆弱的#ifdef
,而是可以检查函数是否使用构建系统进行编译,并相应地定义自己的常量,例如HAVE_FTELLO64
。
请注意,如果您确实决定使用lseek
/ _lseeki64
系列和数字文件描述符而不是FILE*
结构,那么您应该注意open
之间的以下差异/ fopen
:
open
不使用缓冲,fopen
会使用缓冲。减少缓冲意味着性能更差。 open
无法对文本文件执行换行转换,fopen
可以。
参考文献: