Подтвердить что ты не робот

Fgetpos/fsetpos и ftell/fseek

В чем разница между fgetpos/fsetpos и ftell/fseek? Для чего нужны fgetpos и fsetpos?

4b9b3361

Ответ 1

Ну, из manpage мы видим, что ftell и fseek используют тип long int для представления смещений (позиций) в файле и поэтому могут быть ограничены смещениями, которые могут быть представлены в длинном int. (Тип long int не может содержать значения больше 2 ** 31-1, ограничивая максимальное смещение до 2 гигабайт). С другой стороны, новые функции fgetpos и fsetpos используют специальный typedef, fpos_t, для представления смещений. Тип за этим typedef, если он выбран соответствующим образом, может представлять собой сколь угодно большие смещения, поэтому fgetpos и fsetpos могут использоваться с произвольно огромными файлами. fgetpos и fsetpos также записывают состояние, связанное с многобайтовыми потоками.

Ответ 2

Ни один из приведенных выше ответов не верен. Фактически, если вы используете 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.

Ответ 3

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.

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

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

Ответ 4

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