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

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

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

上述答案都不正确 – 事实上,如果您与fseek交替使用fsetpos ,则可能会引入安全漏洞( https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=20087255 )。

原因是fsetposfpos_t *pos参数实际上不是整数,因此它不能用于搜索文件中的任意位置。 因此,唯一有效的值是从fgetpos获得的fgetpos 。 正如文档所说,

与stream相关联的内部文件位置指示符被设置为pos表示的位置, pos是指向fpos_t对象指针,该fpos_t对象的值之前已通过调用fgetpos

http://www.cplusplus.com/reference/cstdio/fsetpos/

如果您想要的是能够寻找超出32位边界的任意位置,那么使用ftello / fseeko并使用#define _FILE_OFFSET_BITS 64编译。

好吧,从联机帮助页我们可以看到ftell和fseek使用类型long int来表示文件中的偏移量(位置),因此可能限于可以用long int表示的偏移量。 (类型long int不保证保持大于2 ** 31-1的值,将最大偏移限制为2千兆字节)。 另一方面,较新的fgetpos和fsetpos函数使用特殊的typedef(fpos_t)来表示偏移量。 这种typedef背后的类型,如果选择得当,可以代表任意大的偏移量,因此fgetpos和fsetpos可以与任意大的文件一起使用。 fgetpos和fsetpos还记录与多字节流相关联的状态。

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()更好更容易。

虽然界面的定义不同,但在function上没有区别。 它们都是实现的,因为它们都是POSIX的一部分。