в чем разница между 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.