Рассмотрим некоторые функции, которые могут пригодиться для работы с файлами (они работают с любыми файлами, но чаще применяются к бинарным):
int fileno(FILE *f) | – возвращает значение дескриптора файла f - fd (число, определяющее номер файла); |
long filelength(int fd) | – возвращает длину в байтах файла, имеющего номер (дескриптор) fd; Часто поэтому применяется вместе с fileno(); |
int chsize(int fd, long pos) | – выполняет изменение размера файла, имеющего номер fd, конец файла устанавливается после байта с номером pos; |
intfseek(FILE *f, long size, int kod) | – выполняет смещение указателя позиции в файле f на size байт в направлении признака kod: 0 - от начала файла; 1 - от текущей позиции указателя; 2 - от конца файла. Заметим, что при kod>0 может быть size<0. |
long ftell(FILE *f) | – возвращает значение указателя позиции в файле (-1 – ошибка); |
intfgetpos(FILE *f, long *pos) | – определяет значение текущей позиции pos файла f, возвращает 0 при успешном завершении. |
Функция fseek может многократно ускорять и упрощать работу с файлами, т.к. она позволяет начать чтение/запись в файле сразу с требуемого места. Подобный способ работы называется прямым доступом к файлу, в отличие от обычного, последовательного доступа, когда информация читается последовательно, от начала к концу. Прямой доступ широко применяется для баз данных. Однако прямой доступ применяется в основном для бинарных файлов (в текстовых файлах трудно вычислить значение нужной позиции в байтах, т.к. разные строки могут иметь разную длину).
При расчете смещения для fseek может пригодиться операция sizeof.
Замечание. Из-за буферизации (см. выше) непосредственно после операции записи нельзя выполнять чтение, и наоборот (не считая случая, когда при чтении достигнут конец файла, что гарантирует исчерпание буфера). Либо файл должен быть переоткрыт заново, либо указатель позиции должен быть установлен в заданное место с помощью fseek.