38

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

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

4

4 回答 4

27

以上答案都不是正确的——事实上,如果你可以fsetpos互换使用,fseek你可能会引入一个安全漏洞(https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=20087255)。

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

与流关联的内部文件位置指示符设置为由 表示的位置pos,它是指向一个fpos_t对象的指针,该对象的值应先前已通过调用 获得fgetpos

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

如果您想要的只是寻找超出 32 位边界的任意位置的能力,请使用ftello/fseeko并使用#define _FILE_OFFSET_BITS 64.

于 2014-01-10T11:03:51.173 回答
18

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

于 2010-07-27T22:52:14.283 回答
4

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()。但我没有在标准 C 库中看到 filelength() 。

因此,您可以做的是使用 fseek() 到文件 END 之前的 0 个字节。然后使用 ftell() 以字节为单位获取位置,并以此为基础计算堆内存量。

你还能做些什么来获取文件大小?您可以使用 fgetc() 来读取每个字符,一直数到最后。但我认为使用 fseek() 和 ftell() 更好更容易。

于 2014-06-13T03:06:27.007 回答
-3

尽管接口定义不同,但功能上没有区别。它们都被实现了,因为它们都是 POSIX 的一部分。

于 2010-07-27T22:52:44.113 回答