Функции fseek
и ftell
определены стандартом языка ISO C.
Ниже приводится последний открытый проект стандарта C 2011 года, но стандарты ISO C 1990, 1999 и 2011 годов очень похожи в этой области, если не идентичны.
7.21.9.4:
Функция ftell получает текущее значение позиции файла
индикатор потока, на который указывает stream . Для двоичного потока
значение - это количество символов в начале файла.
Для текстового потока его индикатор положения файла содержит неопределенный
информация, используемая функцией fseek для возврата файла
индикатор положения потока в его положение во время
ftell вызов; разница между двумя такими возвращаемыми значениями не
обязательно значимая мера количества написанных символов
или читать.
7.21.9.2:
Функция fseek устанавливает индикатор положения файла для потока
на который указывает stream . Если происходит ошибка чтения или записи, ошибка
Индикатор для потока установлен и fseek не работает.
Для двоичного потока - новая позиция, измеренная в символах из
начало файла, получается путем добавления offset к
позиция указана откуда . Указанная позиция является
начало файла, если откуда равно SEEK_SET , текущее значение
индикатора положения файла, если SEEK_CUR , или конец файла, если
SEEK_END . Бинарный поток не обязательно должен поддерживать fseek вызовов со значением откуда SEEK_END .
Для текстового потока либо смещение должно быть равно нулю, либо смещение
должно быть значением, возвращенным ранее успешным вызовом
ftell функция для потока, связанного с тем же файлом, и , откуда должно быть SEEK_SET .
Нарушение любого из условий "must" делает поведение вашей программы неопределенным.
Так, если файл был открыт в двоичном режиме, ftell
дает вам количество символов от начала файла - но fseek
относительно конца файла (SEEK_END
) не обязательно осмысленный. Это подходит для систем, которые хранят двоичные файлы в целых блоках и не отслеживают, сколько было записано в последний блок.
Если файл был открыт в текстовом режиме, вы можете искать начало или конец файла со смещением 0, или вы можете искать позицию, заданную ранним вызовом ftell
; fseek
с любыми другими аргументами имеет неопределенное поведение. Это подходит для систем, в которых количество символов, считываемых из текстового файла, не обязательно соответствует количеству байтов в файле. Например, в Windows при чтении пары CR-LF ("\r\n"
) читается только один символ, но в файле увеличивается на 2 байта.
На практике в Unix-подобных системах текстовый и двоичный режимы ведут себя одинаково, и метод fseek / ftell будет работать. Я подозреваю, это будет работать в Windows (я предполагаю, что ftell
даст смещение в байтах, которое может не совпадать с количеством раз, которое вы могли бы вызвать getchar()
в текстовом режиме).
Обратите внимание, что ftell()
возвращает результат типа long
. В системах, где long
составляет 32 бита, этот метод не может работать с файлами размером 2 ГБ или более.
Возможно, вам лучше использовать какой-нибудь системный метод, чтобы получить размер файла. Поскольку метод fseek / ftell в любом случае зависит от системы, например, stat()
в Unix-подобных системах.
С другой стороны, fseek
и ftell
могут работать, как вы ожидаете, на большинстве систем, с которыми вы, вероятно, столкнетесь. Я уверен, что есть системы, где это не будет работать; извините, но у меня нет подробностей.
Если работа в Linux и Windows достаточно хороша, и вас не интересуют большие файлы, тогда метод fseek / ftell, вероятно, подходит.В противном случае вам следует рассмотреть возможность использования системного метода для определения размера файла.
И помните, что все, что говорит вам о размере файла, может сообщить вам только его размер в этот момент.Размер файла может измениться, прежде чем вы получите к нему доступ.