使用函数fgetpos()
和fsetpos()
并使用函数ftell()
和fseek()
获取和设置文件中的位置有什么区别?
fgetpos()
和fsetpos()
有什么用?为什么要使用它们而不是ftell()
和fseek()
?
答案 0 :(得分:21)
上述答案均不正确 - 事实上,如果您与fsetpos
互换使用fseek
,则可能会引入安全漏洞(https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=20087255)。< / p>
原因是fpos_t *pos
的{{1}}参数实际上不是整数,因此它不能用于搜索文件中的任意位置。因此,唯一有效的值是从fsetpos
获得的值。正如文档所说,
与流关联的内部文件位置指示符设置为
fgetpos
表示的位置,pos
是指向fpos_t
对象的指针,其值之前已通过调用获得fgetpos
。强>
(http://www.cplusplus.com/reference/cstdio/fsetpos/)
如果你想要的是能够寻找超过32位边界的任意位置,那么使用ftello
/ fseeko
并使用#define _FILE_OFFSET_BITS 64
进行编译。
答案 1 :(得分:17)
好吧,从联机帮助页我们可以看到ftell和fseek使用类型long int来表示文件中的偏移量(位置),因此可能限于可以用long int表示的偏移量。 (类型long int不保证保持大于2 ** 31-1的值,将最大偏移限制为2千兆字节)。另一方面,较新的fgetpos和fsetpos函数使用特殊的typedef(fpos_t)来表示偏移量。这个typedef背后的类型,如果选择得当,可以代表任意大的偏移量,因此fgetpos和fsetpos可以用于任意大的文件。 fgetpos和fsetpos还记录与多字节流相关联的状态。
答案 2 :(得分:3)
fgetpos()与fsetpos()一起使用。 ftell()与fseek()一起使用。
fgetpos()看起来几乎像ftell(),因为它们都采用FILE *参数,并且都返回文件中的某种位置,尽管样式略有不同。但是得到这个:只有fseek()允许你从文件的开头,从文件的当前位置,以及从文件末尾向后搜索(fseek()的第三个参数是SEEK_SET,SEEK_CUR和SEEK_END )。 fsetpos()不会这样做。 fsetpos()仅限于回到你从fgetpos()获得的某个位置。
我们假设您要将文件读入内存。你需要从malloc()多少堆?你需要文件的大小。我还没有在C标准库中找到任何可以告诉你文件大小的函数,尽管有些C编译器可能会添加一个非标准函数。例如,Borland Turbo C有filelength()。但我还没有在STANDARD C Library中看到过filelength()。
所以,你可以做的是在文件的END之前使用fseek()到0字节。然后使用ftell()以字节为单位获取位置,并根据其计算堆内存量。
你还能做些什么才能获得文件大小?您可以使用fgetc()读取每个字符,直到结束为止。但我认为使用fseek()和ftell()更好更容易。
答案 3 :(得分:-2)
虽然界面的定义不同,但在功能上没有区别。它们都是实现的,因为它们都是POSIX的一部分。