what is difference between fgetpos/fsetpos and ftell/fseek

六眼飞鱼酱① 提交于 2019-11-27 18:09:57

None of the above answers are correct - in fact if you use fsetpos interchangeably with fseek you could introduce a security flaw (https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=20087255).

The reason is that the fpos_t *pos argument to fsetpos isn't actually an integer so it can't be used to seek to arbitrary locations in a file. The only valid values are therefore ones obtained from fgetpos. As the docs say,

The internal file position indicator associated with stream is set to the position represented by pos, which is a pointer to an fpos_t object whose value shall have been previously obtained by a call to fgetpos.

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

If all you want is the ability to seek to arbitrary locations beyond 32-bit boundary, then use ftello / fseeko and compile with #define _FILE_OFFSET_BITS 64.

Well, from the manpage we can see that ftell and fseek use type long int to represent offsets (positions) in a file, and may therefore be limited to offsets which can be represented in a long int. (Type long int is not guaranteed to hold values larger than 2**31-1, limiting the maximum offset to 2 gigabytes). The newer fgetpos and fsetpos functions, on the other hand, use a special typedef, fpos_t, to represent the offsets. The type behind this typedef, if chosen appropriately, can represent arbitrarily large offsets, so fgetpos and fsetpos can be used with arbitrarily huge files. fgetpos and fsetpos also record the state associated with multibyte streams.

fgetpos() goes with fsetpos(). And ftell() goes with fseek().

fgetpos() looks practically like ftell() because both take a FILE* parameter, and both return some kind of position in the file, albeit with a slightly different style. But get this: ONLY fseek() allows you to seek from the beginning of the file, from your current position in the file, and backwards from the end of the file (the third argument to fseek() being SEEK_SET, SEEK_CUR, and SEEK_END). fsetpos() doesn't do this. fsetpos() is limited to going back to some position you got from fgetpos().

Let us say you want to read a file into memory. How much heap do you need from malloc()? You need the size of the file. And I have yet to find any function in the C Standard Library that will tell you the size of a file, though some C Compilers may add a non-standard function. For example, Borland Turbo C had filelength(). But I have not seen filelength() amongst the STANDARD C Library.

So, what you can do is use fseek() to 0 bytes before the END of the file. Then use ftell() to get the position in bytes, and base your calculation for amount of heap memory on that.

What else could you do to get the file size? You could use fgetc() to read each character, counting until you get to the end. But I think using fseek() and ftell() is better and easier.

m1tk4

There is no difference in the functionally, although the interfaces are defined differently. They both are implemented because both are part of POSIX.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!