Глава 5. Дисковые накопители.

Раздел 4. Чтение и запись файла.

5.4.6 Чтение из файлов прямого доступа.

Чтение файлов прямого доступа является обратным процессом по отношению к их записи. MS DOS вычисляет позицию в файле на диске, затем считывает запись и помещает ее в память. Затем программа должна разделить запись на поля в точности того же размера, который был использован при конструировании записи. Hе забудьте удалить символы пробела, добавленные при заподнении полей. Обсуждение записи данных в файлы прямого доступа {5.4.5} содержит информацию, которая поможет Вам лучше понять информацию данного раздела.

Средний уровень.

Метод FCB доступа к файлам имеет две функции для чтения записей с прямым доступом. С другой стороны, метод дескриптора файлов использует ту же функцию, что и для чтения последовательных файлов. Два метода доступа рассматриваются отдельно. Метод FCB:

Функция 21H прерывания 21H читает одну запись из файла прямого доступа. Вторая функция, 27H, читает блок последовательных записей. Создайте управляющий блок файла, как показано в {5.3.5} и откройте его {5.3.3}. После того как FCB открыт, введите в него значения полей размера записи (DW по смещению 14) и номера записи прямого доступа (DD по смещению 33). Если DS:DX указывают на первый байт FCB, то можно вызывать функцию 21H для чтения записи и запись будет помещена в паямть, начиная с первого байта DTA.

Если запись успешно прочитана, то в AL будет возвращен 0. Однако при этом нет гарантии, что чтение прошло без ошибок, поскольку неверный размер записи может привести к тому, что части прилегающих записей будут считаны, как будто это одна запись. Если запрошена запись с номером большим, чем число записей в файле, то в AL будет возвращено 1 или 3. Если был возвращен код 3, то был считан самый конец файла и была прочитана часть записи данных. Если был возвращен код 1, то данные вообще не были считаны.

Данный пример считывает одну запись и помещает ее в DTA:
;---в сегменте данных
FCB DB 1,'OLDDATA ', 25 DUP (0)
;---открываем файл и устанавливаем поля FCB
MOV AH,0FH ;номер функции
LEA DX,FCB ;DS:DX указывают на FCB
MOV BX,DX ;копируем смещение FCB
INT 21H ;открываем файл
MOV AX,55 ;размер записи 55 байтов
MOV [BX]+14,AX ;помещаем в поле размера записи
MOV AX,22 ;номер записи для чтения
MOV [BX]+33,AX ;помещаем в поле номера записи
MOV AX,0 ;обнуляем старшее слово этого поля
MOV [BX]+35,AX ;
;---перенос данных из файла в DTA
MOV AH,21H ;номер функции чтения с прямым доступом
LEA DX,FCB ;DS:DX указывают на FCB
INT 21H ;читаем данные, помещая их в DTA
CMP AL,0 ;проверка на ошибку
JNE READ_ERROR ;
;---позднее, закрываем файл
MOV AH,10 ;номер функции закрытия файла
LEA DX,FCB ;DS:DX указывают на FCB
INT 21H ;закрываем файл

Для чтения блока последовательных записей в память за один прием надо использовать функцию 27H прерывания 21H. Ее выполнение подготавливается в точности так же, как и функции 21H, за исключением того, что вдобавок CX должен содержать число записей которые надо прочитать за один прием. При возврате CX будет содержать число реально прочитанных записей. Значения возвращаемые в AL совпадают с теми, которые возвращаеются функцией 21H. В отличии от функции 21H поля FCB, в которых хранится информация о положении записи (поле записи прямого доступа, текущего блока и текущей записи) автоматически увеличиваются, с тем чтобы они указывали на следующую несчитанную запись после выполнения функции.

Отметим, что как в случае чтения одной, так и в случае чтения нескольких записей, поля текущего блока и текущей записи FCB устанавливаются по значению поля записи прямого доступа. Если Вы знаете значение текущего блока и текущей записи, а не соответствующий номер записи прямого доступа, то используйте функцию 24H прерывания 21H, чтобы она проделала вычисления за Вас. У этой функции нет входных регистров, надо только, чтобы DS:DX указывали на открытый FCB. При возврате поле записи прямого доступа будет заполнено значением, соответствующим установке двух других полей.

Метод дескриптора файлов:

В предыдущем разделе показано, как писать записи прямого доступа с помощью метода дескриптора файлов. Процедура чтения из файла с прямым доступом подготавливается совершенно аналогичным образом, путем вычисления смещения в файле, на которое должен указывать файловый указатель. DS:DX должны указывать на буфер, в который будет помещена запись, после чего надо выполнить функцию 3FH прерывания 21H. При входе CX должен содержать размер записи, а BX - номер файла.
;---в сегменте данных
HANDLE DB ?
FILEPATH DB 'A:OLDDATA',0
REC_BUFFER DB 30 DUP(?)
;---открываем файл
MOV AH,3DH ;номер функции
MOV AL,0 ;код открытия для чтения
LEA DX,FILEPATH ;DS:DX указывают на путь к файлу
INT 21H ;открываем файл
JC OPEN_ERROR ;проверка на ошибку
MOV HANDLE,AX ;запоминаем номер файла
;---вычисляем позицию записи и устанавливаем файловый указатель
MOV AX,30 ;размер записи
MOV CX,54 ;читаем запись #54 (55-ю запись)
MUL CX ;смещение записи в DX:AX
MOV CX,DX ;помещаем старшее слово смещения в DX
MOV DX,AX ;помещаем младшее слово смещения в CX
MOV AL,0 ;устанавливаем указатель на начало файла
MOV AH,42H ;функция установки указателя
MOV BX,HANDLE ;номер файла
INT 21H ;устанавливаем указатель
JC POINTER_ERROR ;обработка ошибки
;---читаем запись с прямым доступом
MOV AH,3FH ;номер функции
MOV BX,HANDLE ;номер файла
MOV CX,30 ;размер записи
LEA DX,REC_BUFFER ;DS:DX указывают на буфер для записи
INT 21H ;читаем запись
JC READ_ERROR ;обработка ошибки
;---позднее, закрываем файл
MOV BX,HANDLE ;номер файла
MOV AH,3EH ;функция закрытия файла
INT 21H ;закрываем файл
JC CLOSE_ERROR ;проверка на ошибку


<~-5.4.5 Запись в файлы прямого доступа.
Содержание
5.4.7 Проверка данных после операций чтения/записи.-~>

Сайт управляется системой uCoz