fgetpos / fsetpos和ftell / fseek有什么区别

时间:2010-07-27 22:49:25

标签: c c-standard-library

使用函数fgetpos()fsetpos()并使用函数ftell()fseek()获取和设置文件中的位置有什么区别?

fgetpos()fsetpos()有什么用?为什么要使用它们而不是ftell()fseek()

4 个答案:

答案 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的一部分。