Справочник программиста на персональном компьютере фирмы IBM. Дисковые накопители - Получение/установка размера файла
ОГЛАВЛЕНИЕ
5.1.3 Получение/установка размера файла.
Программа может пожелать проверить размер файла по разным
причинам. Одна из возможных причин состоит в определении числа
записей, содержащихся в файле. Другая - в определении позиции
конца файла, с тем чтобы файловый указатель был установлен верно
для добавления в файл новых данных, без изменения существующих.
Конечно, размер файла устанавливается автоматически функцией
DOS. Иногда программа может нуждаться в резервировании дискового
пространства для дальнейшего использования. В этом случае надо
открыть файл в режиме прямого доступа и записать такой номер
записи, чтобы файл имел достаточную длину. Записи между "фиктив-
ной" и реально относящимися к файлу будут заполнены теми данными,
которые случайно окажутся в дисковых секторах, отведенных для
файла при этой операции.
Высокий уровень.
В Бейсике функция LOF (длина файла) возвращает точное число
байтов, отведенных файлу (предупреждаем, однако, что старые вер-
сии Бейсика - 1.х - возвращают число 128-байтных блоков, исполь-
зуемых файлом). Файл должен быть открыт и ссылаться на него надо
по номеру, под которым был открыт файл. Формат X = LOF(1). В
следующем примере определяется сколько 64-байтных записей содер-
жится в файле, открытом как #3:
100 OPEN "FILENAME" AS #3 'открываем файл
110 RECORDLEN = 64 'определяем длину записи
120 NUMBREC = LOF(3)/RECORDLEN 'вычисляем число записей
Средний уровень.
FCB функция 23H прерывания 21H сообщает число записей в файле.
Если приписать файлу длину записи в 1 байт, то его размер будет
возвращен в байтах. DS:DX должны указывать на управляющий блок
открытого файла. Затем вызовите функцию. Если файл не найден, то
в AL возвращается FF. В противном случае в AL возвращается 0, а
число записей помещается в поле номера записи прямого доступа FCB
(байты 33-36). Для правильной работы поле длины записи FCB должно
быть установлено после открытия файла, но перед вызовом функции;
это двухбайтное поле расположено по смещению 14 в FCB. Если раз-
мер файла неточно делится на длину записи, то сообщаемое число
записей округляется вверх. Вот пример, в котором используется
длина записи равная 1:
;---определение размера файла
LEA DX,FCB ;DS:DX указывает на FCB
MOV BX,DX ;копируем указатель в BX
MOV CX,1 ;размер записи в CX
MOV [BX]+14,CX ;пишем в поле размера записи FCB
MOV AH,23H ;функция сообщающая размер файла
INT 21H ;вызов функции
MOV AX,[BX]+33 ;получаем младшую часть размера файла
MOV CX,[BX]+35 ;получаем старшую часть размера файла
Можно также устанавливать длину файла, используя управляющие
блоки файла. Для этого надо использовать функцию записи блока с
прямым доступом, которая обсуждается в [5.4.5]. У этой функции
имеется частный случай, когда число записанных записей устанавли-
вается равным нулю, то длина файла устанавливается равной числу
записей, указанному в поле записи прямого доступа.
Метод, использующий дескриптор файла (file handle) не имеет
функции, которая непосредственно сообщала бы длину файла, однако
имеется возможность вычислить размер, передвинув указатель файла
с начала на конец файла. При открытии файла указатель файла авто-
матически устанавливается на первый байт файла. Указатель файла
перемещается функцией 42H прерывания 21H. Надо поместить в AL
кодовое число 2, напраляющее указатель на конец файла. В BX дол-
жен быть указан номер файла, а CX:DX содержит смещение от конца
файла до позиции, в которую должен быть установлен указатель,
поэтому поместите 0 в оба этих регистра. Затем вызовите функцию.
При возврате DX:AX будет содержать новую позицию указателя, отно-
сительно его предыдущей позиции - т.е. будет содержать длину
файла (DX содержит старший байт). При возникновении ошибки будет
установлен флаг переноса, а в AX будет возвращено 1, если непра-
вилен номер функции и 6, если неправилен номер файла. Не забудьте
затем снова вернуть указатель на начало файла, если это необходи-
мо. Поместите 0 в AL, CX и DX и вызовите функцию снова. Вот при-
мер:
;---открываем файл
LEA DX,FILE_PATH ;DS:DX указывают на путь файла
MOV AL,0 ;открываем для чтения
MOV AH,3DH ;функция открытия файла
INT 21H ;открываем его
JC OPEN_ERROR ;проверка на ошибку
MOV HANDLE,AX ;запоминаем номер файла
;---определяем длину файла
MOV AH,42H ;функция перемещения указателя
MOV AL,2 ;код установки на конец файла
MOV BX,HANDLE ;номер файла в BX
MOV CX,0 ;0 в CX и DX
MOV DX,0 ;
INT 21H ;сдвигаем указатель
JC POINTER_ERROR ;ошибка?
MOV FSIZE_HIGH,DX ;запоминаем размер файла
MOV FSIZE_LOW,DX ;