fgetpos()
和 fsetpos()
与使用 ftell()
和 fseek()
函数来获取和设置文件位置的区别在哪里?
fgetpos()
和 fsetpos()
有什么作用?为什么会使用它们而不是使用 ftell()
和 fseek()
呢?
fgetpos()
和 fsetpos()
与使用 ftell()
和 fseek()
函数来获取和设置文件位置的区别在哪里?
fgetpos()
和 fsetpos()
有什么作用?为什么会使用它们而不是使用 ftell()
和 fseek()
呢?
fsetpos
与fseek
互换使用,则可能会引入安全漏洞(https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=20087255)。fsetpos
的fpos_t *pos
参数实际上不是整数,因此不能用于在文件中寻找任意位置。因此,唯一有效的值是从fgetpos
获得的值。正如文档所述,
(http://www.cplusplus.com/reference/cstdio/fsetpos/)与流相关联的内部文件位置指示器设置为由
pos
表示的位置,其中pos
是指向fpos_t
对象的指针,其值先前应通过调用fgetpos
获得。
ftello
/ fseeko
并使用#define _FILE_OFFSET_BITS 64
进行编译即可。fpos_t
可能根本不是整数(标准并不要求它是整数)。 - Meckiftello
和fseeko
是POSIX函数。此外,C11标准在7.21.9.1中指出:“如果有的话,fgetpos函数将流stream所指向的解析状态和文件位置指示器的当前值存储在pos所指向的对象中。”此外,在7.21.1中指出:“fpos_t
是一个完整的对象类型,而不是数组类型,能够记录指定文件中每个位置所需的所有信息。”然而,在我的系统上,fpos_t
至少是一个__darwin_off_t
,它实际上是一个__int64_t
。尽可能使用fsetpos和fgetpos。 - math根据 man 手册,我们可以看到 ftell 和 fseek 使用 long int 类型来表示文件中的偏移量(位置),因此可能会受限于 long int 可以表示的偏移量范围(long int 类型不能保证能够保存大于 2^31-1 的值,最大偏移量限制为 2GB)。然而,新版的 fgetpos 和 fsetpos 函数使用了一个特殊的 typedef,fpos_t,来表示偏移量。如果选择恰当的类型,该 typedef 背后的类型可以表示任意大小的偏移量,因此 fgetpos 和 fsetpos 可以用于处理任意巨大的文件。此外,fgetpos 和 fsetpos 还记录与多字节流相关联的状态。
2 ** 31-1
以外的位置,那么可以使用fseeko
。正确的答案是fgetpos
只能定位到先前由fgetpos
获取的位置,而且不能将fpos_t
解释为整数。正如手册中所说:“在某些非UNIX系统上,fpos_t对象可能是一个复杂的对象,这些例程可能是可移植重新定位文本流的唯一方法。” - Meckifseek
和相关函数的限制,并正确地指出 fgetpos
和相关函数是没有这些限制的选择。上面的答案从未说明过可以混合使用 fseek
和 fsetpos
及其相关函数,这是确实危险的。此外,它也从未说明 fpos_t
是一个整数类型。相反,Mecki 建议使用非 ISO-C 标准函数(但是 POSIX 函数) fseeko
和相关函数。 - mathfgetpos()与fsetpos()配对使用,而ftell()则与fseek()搭配使用。
fgetpos()和ftell()看起来很相似,因为两者都需要FILE*类型的参数,并且都返回文件中的某种位置,尽管风格稍有不同。但是请注意:只有fseek()允许您从文件开头、当前位置和文件末尾向后搜索(fseek()的第三个参数分别为SEEK_SET、SEEK_CUR和SEEK_END)。fsetpos()无法实现这一点。fsetpos()仅限于返回您从fgetpos()获取的某个位置。
假设你想要将文件读入内存。你需要从malloc()获取多少堆内存?你需要知道文件的大小。我还没有发现C标准库中有任何函数可以告诉您文件的大小,尽管某些C编译器可能会添加一个非标准函数。例如,Borland Turbo C拥有filelength()函数。但我在标准C库中没有看到filelength()函数。
所以,你可以使用fseek()函数将指针定位到文件结尾前的0字节处。然后使用ftell()获取字节位置,并按照此计算出所需的堆内存量。
还有其他方法可以获取文件大小吗?您可以使用fgetc()函数读取每个字符,计数直到达到文件末尾。但我认为使用fseek()和ftell()更好、更容易。
在功能上没有区别,尽管接口定义不同。它们都被实现,因为它们都是 POSIX 的一部分。
long int
或 fpos_t
。 - math