MS-DOS для программиста© Александр Фролов, Григорий ФроловТом 19, М.: Диалог-МИФИ, 1995, 253 стр. 3.6. ПозиционированиеУправляя содержимым файлового указателя позиции программа может произвольно считывать или перезаписывать различные участки файла, то есть организовать прямой доступ к содержимому файла. Прямой доступ к файлу может вам пригодиться, например, для создания системы управления базами данных. Установка файлового указателяУстановить файловый указатель в нужную вам
позицию можно с помощью функции 42h прерывания
INT 21h :
Функция 42h позволяет указывать новое значение указателя либо как абсолютное смещение от начала файла, либо как смещение от текущей позиции, либо как смещение от конца файла. В последних двух случаях используется смещение со знаком. Для указания смещения или абсолютной позиции программа должна задать в регистрах CX, DX соответствующее 32-битное значение. Что произойдет, если при использовании методов кодирования 01h или 02h попытаться установить указатель позиции до начала файла? Функция 42h при этом не возвратит признак ошибки, однако если будет сделана попытка прочитать или записать данные, то соответствующая функция чтения/записи завершится с ошибкой. Определение размера файлаЕсли использовать метод кодирования 02h и при этом задать нулевое смещение, функция установит указатель на конец файла. Это обстоятельство может быть использовано для определения размера файла в байтах. Функции библиотеки Borland C++Стандартная библиотека Borland C++ содержит функции, предназначенные для управления файловым указателем позиции и получения текущего значения этого указателя. Это функции lseek , tell , filelength . lseekФункция lseek работает аналогично только что описанной функции 42h. Приведем ее прототип: long lseek (int handle, long offset, int origin); Первый параметр определяет файл, для которого
выполняется операция позиционирования. Параметр
offset определяет смещение. Последний параметр
задает метод кодирования смещения. Он может
принимать следующие значения, описанные в фале
stdio.h:
Функция возвращает величину текущего смещения в байтах относительно начала файла или -1 в случае ошибки. Как и для остальных функций библиотеки, код ошибки находится в глобальной переменной errno. filelengthВы, конечно, можете использовать функцию lseek для определения размера файла или текущей файловой позиции. Однако для того чтобы узнать размер файла, лучше воспользоваться специальной функцией filelength : long filelength (int handle); Эта функция возвращает размер файла в байтах. Файл задается параметром handle. В случае ошибки функция возвращает значение -1. tellДля того, чтобы определить текущую файловую позицию, можно использовать функцию tell : long tell (int handle); Эта функция возвращает текущую позицию для файла, определенного параметром handle, или -1 в случае ошибки. Программа SETPOSДля демонстрации использования функций позиционирования приведем простую программу SETPOS (листинг 3.5), которая для заданного файла и позиции внутри файла отображает содержимое одного байта. Дополнительно программа определяет размер файла и текущую позицию после чтения байта. Листинг 3.5. Файл setpos\setpos.cpp #include <io.h> #include <stdio.h> #include <fcntl.h> int main(void) { int handle; long position, length; char buffer[2], fname[80]; // Запрашиваем имя файла, с которым будем работать printf("Введите имя файла: "); gets(fname); // Открываем файл handle = open (fname, O_BINARY | O_RDONLY ); // Если такого файла нет, выводим сообщение об ошибке // и завершаем работу программы if(handle == -1) { printf("\nНет такого файла!"); return(-1); } // Определяем и выводим на экран // размер файла в байтах length = filelength (handle); printf("\nДлина файла %s составляет %ld байт\n", fname, length); // Запрашиваем позицию для чтения и отображения байта do { printf("Введите позицию: "); scanf ("%ld", &position); } while(position > length); // Устанавливаем заданную позицию lseek (handle, position, SEEK_SET ); // Читаем один байт в буфер, начиная с установленной // позиции if(read (handle, buffer, 1) == -1) { // Для вывода сообщения об ошибке используем // функцию perror(), которая добавляет к сообщению, // заданному в параметре, расшифрованное // системное сообщение об ошибке. // Код ошибки функция perror() берет // из переменной errno perror("Ошибка при чтении"); return(-1); } // Выводим считанный байт на экран printf( "Смещение: %ld; байт: %02.2x ('%c')\n", position, (unsigned char)*buffer, *buffer); // Определяем текущую позицию и выводим ее // на экран position = tell (handle); printf("\nТекущая позиция в файле: %ld\n", position); // Закрываем файл close (handle); return 0; } |