в чем разница между fgetpos / fsetpos и ftell/fseek

в чем разница между использованием функций fgetpos() и fsetpos() и использование функций ftell() и fseek() получить и установить позицию в файле?

каковы fgetpos() и fsetpos() хороши? Почему они должны использоваться вместо ftell() и fseek()?

4 ответов


ни один из приведенных выше ответов не является правильным - в самом деле, если вы используете fsetpos взаимозаменяемо с fseek вы можете ввести недостаток безопасности(https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=20087255).

причина в том, что до fsetpos на самом деле не целое число, поэтому его нельзя использовать для поиска произвольных местоположений в файле. Поэтому единственными допустимыми значениями являются значения, полученные из fgetpos. Как врачи говорят:

индикатор положения внутреннего файла, связанный с потоком, устанавливается в положение, представленное pos, который является указателем на fpos_t объект значение которого должно быть предварительно получено вызовом fgetpos.

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

если все, что вы хотите, это возможность искать произвольные местоположения за пределами 32-битной границы, а затем использовать ftello / fseeko и компилировать с #define _FILE_OFFSET_BITS 64.


Ну, из manpage мы можем видеть, что 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 () среди стандартного C Библиотека.

Итак, вы можете использовать fseek() до 0 байт до конца файла. Затем используйте ftell (), чтобы получить позицию в байтах, и основывайте на этом свои вычисления для объема памяти кучи.

Что еще можно сделать, чтобы получить размер файла? Вы можете использовать fgetc() для чтения каждого символа, считая до конца. Но я думаю, что использование fseek () и ftell () лучше и проще.


нет никакой разницы в функционально, хотя интерфейсы определены по-разному. Они оба реализованы, потому что оба являются частью POSIX.