Прежде, чем перейти к упомянутому примеру, необходимо рассмотреть
формируемую DOS структуру данных - блок управления файлом FCB (File
Control Block), который является существенным элементом файловой
системы и участвует во всех файловых операциях.
Блок управления файлом обеспечивает связь пользовательской
программы с функциями DOS. При любой файловой операции происходит
обращение к блоку FCB. На Фиг.5.5 показан состав стандартного
блока FCB. Имеется модификация блока FCB, называемая расширенным
блоком FCB, которая применяется в специальных случаях, когда нужно
"скрыть" файл. Скрытый файл защищен от записи. Это значит, что
программа не может модифицировать содержимое этого файла, не
изменив предварительно его блока FCB. Скрытый файл не фигурирует в
листинге справочника. Скрыть файл - один из простейших способов
защиты файла от неумелого пользователя. В приводимых примерах
используются только стандартные блоки FCB.
Поля данных блока FCB охватывают все атрибуты файла. Номер
дисковода, имя и тип файла составляют идентификатор файла. Размер
файла и дата яаляются атрибутами файла, которые приводятся в
листинге справочника. Оставшиеся поля - текущий номер блока, длина
записи и номер записи при произвольном доступе - служат для
определения местоположения внутри файла при операциях чтения и
записи. Длина записи указывает на число байтов в определяемой
пользователем записи. Так как все операции чтения и записи в файл
начинаются с границы записи, то длина записи определяет количество
данных, обрабатываемых во время каждой из этих операций.
Существуют два способа определения текущей записи при обращении
к файлу. При первом, последовательном, способе записи
обрабатываются по порядку. При этом текущий номер блока и
относительный номер записи определяют запись, которая будет
обрабатываться следующей. По мере того, как программа выполняет
операции чтения или записи, DOS увеличивает на 1 относительный
номер записи, чтобы он указывал на следующую запись. Выполнение
ЪДДДДї
0 і і Номер носителя
ГДДДДЕДДДДВДДДДВДДДДВДДДДВДДДДВДДДДВДДДДї
1 і і і і і і і і і Имя файла
ГДДДДЕДДДДЕДДДДЕДДДДБДДДДБДДДДБДДДДБДДДДЩ
9 і і і і Расширение
ГДДДДЕДДДДЕДДДДЩ
0С і і і Текущий блок
ГДДДДЕДДДДґ
0E і і і Размер записи
ГДДДДЕДДДДЕДДДДВДДДДї
10 і і і і і Размер файла
ГДДДДЕДДДДЕДДДДБДДДДЩ
14 і і і Дата
ГДДДДЕДДДДЕДДДДВДДДДВДДДДВДДДДВДДДДВДДДДВДДДДВДДДДДї
16 і і і і і і і і і і і Зарезервировано
ГДДДДЕДДДДБДДДДБДДДДБДДДДБДДДДБДДДДБДДДДБДДДДБДДДДДЩ
20 і і Относительная запись
ГДДДДЕДДДДВДДДДВДДДДї (нумерация в блоке)
21 і і і і і Номер записи
АДДДДБДДДДБДДДДБДДДДЩ прямого доступа
Фиг. 5.5 Блок управления файлом
последовательных операций идет в направлении от начала к концу
файла. Примером последовательного файла служит программный файл на
языке ассемблера. Ассемблер осуществляет чтение записей от начала
до конца этого файла.
Программа может обращаться к файлу, используя также и
произвольный доступ. Произвольный в данном случае не означает, что
запись выбирается случайным образом. Наоборот, это значит, что
программа может выбрать в качестве следующей любую запись в файле.
По-другому такой файл называют файлом с прямым доступом, так как у
программы имеется непосредственный доступ к любой записи.
Программа может обращаться к файлу любым из двух указанных
способов. При последовательных операциях DOS автоматически изменяет
в блоке FCB значение поля относительного номера записи. При
произвольном доступе к файлу номер записи должен определяться
программой. В файловой системе файл с произвольным доступом
является аналогом вектора. Точно так же, как для обращения к любому
элементу вектора программа должна задать значение соответствующего
индекса, так и при обращение к записи в файле с произвольным
доступом номер записи должен определяться программой.
Теперь можно рассмотреть пример программы, использующей блок
FCB и функции DOS. На Фиг. 5.6 приведена длинная программа, которая
реально мало что делает. Ее цель - продемонстрировать использование
блока FCB и функци DOS, связанных с прерыванием 21H. Однако
содержащиеся в этой программе операции могут применяться в реальных
задачах.
Microsoft (R) Macro Assembler Version 5.00
1/1/80 04:02:12
Фиг. 5.6 Пример использования функций ДОС Page
1-1
PAGE
,132
TITLE
Фиг. 5.6 Пример использования функций ДОС
0000 CODE
SEGMENT
005C ORG
05CH ; Положение первого поля FCB
005C FCB LABEL
BYTE ; Метка всего поля FCB
005C ?? FCB_DRIVE DB
? ; Номер устройства
005D 0008[ FCB_NAME DB
8 DUP (?) ; Имя файла
??
]
0065 0003[ FCB_EXT DB
3 DUP (?) ; Тип файла
??
]
0068 ???? FCB_BLOCK DW ? ;
Номер текущего блока
006A ???? FCB_RECORD_SIZE
DW ? ; Размер записи
006C ????????
FCB_FILE_SIZE DD
? ; Размер файла
0070 ???? FCB_DATE
DW ? ; Дата последнего
изменения
0072 000A[ FCB_RESV DB
10 DUP (?) ; Зарезервировано
ДОС
??
]
007C ?? FCB_CURRENT_RECORD
DB ? ; Номер текущей записи
007D ????????
FCB_RANDOM_RECORD DD ?
; Номер записи при прямом
;
доступе
0090 ORG
090H
0090 DISK_TRANSFER_ADDRESS LABEL
BYTE ; Буфер для данных
0100 ORG
100H
ASSUME
CS:CODE,DS:CODE,ES:CODE
0100 E9 01CD R JMP PROGRAM_START
; Переход на начало программы
= 0020 RECORD_SIZE EQU 32
; Размер записи
0103 03 00 00 00 00
KEYBOARD_BUFFER DB 3, 0, 0,
0, 0 ; Буфер ввода с клавиатуры
0108 94 A0 A9 AB 20 E3 A6 FILE_ERROR_MSG DB 'Файл уже
существует', 10, 13, '$'
A5 20 E1 E3 E9 A5 E1
E2 A2 E3 A5 E2 0A 0D
24
011E 8D A5 A2 AE A7 AC AE BAD_OPEN_MSG DB 'Невозможно
открыть файл', 10, 13, '$'
A6 AD AE 20 AE E2 AA
E0 EB E2 EC 20 E4 A0
A9 AB 0A 0D 24
0138 8E E8 A8 A1 AA A0 20 BAD_WRITE_MSG DB 'Ошибка при
записи в файл', 10, 13, '$'
AF E0 A8 20 A7 A0 AF
A8 E1 A8 20 A2 20 E4
A0 A9 AB 0A 0D 24
0153 8E E8 A8 A1 AA A0 20 BAD_READ_MSG DB 'Ошибка при
чтении файла', 10, 13, '$'
AF E0 A8 20 E7 E2 A5
AD A8 A8 20 E4 A0 A9
AB A0 0A 0D 24
016D 8E E8 A8 A1 AA A0 20 BAD_CLOSE_MSG DB 'Ошибка при
закрытии файла', 10, 13, '$'
Фиг. 5.6 Пример использования функциямй DOS (начало)
AF E0 A8 20 A7 A0 AA
E0 EB E2 A8 A8 20 E4
A0 A9 AB A0 0A 0D 24
0189 8F E0 A8 20 A2 A2 AE INPUT_BAD_MSG DB 'При вводе
требуется два символа', 10, 13, '$'
A4 A5 20 E2 E0 A5 A1
E3 A5 E2 E1 EF 20 A4
A2 A0 20 E1 A8 AC A2
AE AB A0 0A 0D 24
01AB 82 A2 AE A4 20 A4 AE CHAR_BAD_MSG DB 'Ввод должен
быть: символ|символ', 10, 13, '$'
AB A6 A5 AD 20 A1 EB
E2 EC 3A 20 E1 A8 AC
A2 AE AB 7C E1 A8 AC
A2 AE AB 0A 0D 24
;-----
Установка буфера (Области связи с диском)
01CD PROGRAM_START:
01CD B4 1A MOV AH, 1AH
; Установка буфера
01CF 8D 16 0090 R
LEA DX, DISK_TRANSFER_ADDRESS
01D3 CD 21 INT 21H
;-----
Поиск файла
01D5 B4 11 MOV AH, 11H
; Поиск файла с заданным
01D7 8D 16 005C R
LEA DX, FCB
; именем
01DB CD 21 INT 21H
01DD 0A C0 OR AL, AL
01DF 75 0A JNZ NO_FILE
; Переход если файл новый
01E1 8D 16 0108 R
LEA DX, FILE_ERROR_MSG ; Сообщение о неправильном
01E5 ERROR_EXIT: ; имени
файла
01E5 B4 09 MOV AH, 9H
; Вывод сообщения на экран
01E7 CD 21 INT 21H
; и выход из программы
01E9 CD 20 INT 20H
;-----
Создание нового файла
01EB NO_FILE:
01EB B4 16 MOV AH, 16H
; Создание файла
01ED 8D 16 005C R
LEA DX, FCB
01F1 CD 21 INT 21H
01F3 0A C0 OR AL, AL ; Проверка на успех
01F5 74 06 JZ CREATE_OK
01F7 8D 16 011E R
LEA DX, BAD_OPEN_MSG
; Сообщение об ошибке при
01FB EB E8 JMP ERROR_EXIT
; создании файла
;-----
Установка параметров FCB
01FD CREATE_OK:
01FD C6 06 007C R 00
MOV FCB_CURRENT_RECORD, 0 ;
Инициализация номера
0202 C7 06 007D R 0000 MOV WORD PTR
FCB_RANDOM_RECORD, 0 ; записи
0208 C7 06 007F R 0000 MOV WORD PTR
FCB_RANDOM_RECORD+2, 0
020E C7 06 006A R 0020 MOV WORD PTR
FCB_RECORD_SIZE, RECORD_SIZE
Фиг. 5.6 Пример использования функциямй DOS (продолжение)
;-----
Вывод в файл
0214 B0 41 MOV AL, 'A' ; В этом цикле выводятся
0216 CHARACTER_LOOP: ; символы
алфавита
0216 8D 3E 0090 R
LEA DI, DISK_TRANSFER_ADDRESS
021A B9 0020 MOV CX,
RECORD_SIZE
021D F3/ AA REP STOSB
; Заполнение буфера символами
021F 50 PUSH AX ; Сохранение символа
0220 8D 16 005C R
LEA DX, FCB
0224 B4 15 MOV AH, 15H
; Последовательный вывод
0226 CD 21 INT 21H
; блока символов
0228 0A C0 OR AL, AL
; Проверка на ошибку
022A 58 POP AX ; Восстановление символа
022B 74 06 JZ WRITE_OK
022D 8D 16 0138 R
LEA DX, BAD_WRITE_MSG ; Ошибка записи
0231 EB B2 JMP ERROR_EXIT
0233 WRITE_OK:
0233 FE C0 INC AL
; Следующий символ
0235 3C 5B CMP AL, 'Z'+1 ; Проверка на окончание вывода
0237 75 DD JNE CHARACTER_LOOP ;
Вывод следующего символа
;-----
Изменение файла
0239 KEYBOARD_LOOP: ; Цикл
ввода символов
0239 8D 16 0103 R
LEA DX, KEYBOARD_BUFFER ;
с клавиатуры и
023D B4 0A MOV AH, 0AH
; изменение файла
023F CD 21 INT 21H
; Ввод с клавиатуры
0241 80 3E 0104 R 02
CMP KEYBOARD_BUFFER+1, 2 ; Было введено два символа?
0246 74 0A JE KEY_INPUT_OK
0248 8D 16 0189 R
LEA DX, INPUT_BAD_MSG ; Сообщение об ошибке
024C KEYBOARD_ERROR:
024C B4 09 MOV AH, 9H
024E CD 21 INT 21H
; Печать сообщения об ошибке
0250 EB E7 JMP KEYBOARD_LOOP
; Повторный ввод
0252 KEY_INPUT_OK:
0252 8D 16 01AB R
LEA DX, CHAR_BAD_MSG
; Установка указателя на
;
сообщение об ошибке
0256 A0 0105 R MOV AL, KEYBOARD_BUFFER+2 ; Выборка первого символа
0259 3C 24 CMP AL, '$' ; Сравнение с символом конца
025B 75 03 JNE CHANGE_RECORD
; Изменение записи
025D EB 5C 90 JMP PROGRAM_EXIT
;-----
Чтение старой записи из файла
0260 CHANGE_RECORD:
0260 3C 41 CMP AL, 'A' ; Проверка на то, что символ
0262 7C E8 JL KEYBOARD_ERROR
; находится в диапазоне A-Z
0264 3C 5A CMP AL, 'Z'
0266 77 E4 JA KEYBOARD_ERROR
0268 2A E4 SUB AH, AH
; Преобразование символа в
026A 2C 41 SUB AL, 'A' ; номер записи
026C A3 007D R MOV word ptr
FCB_RANDOM_RECORD, AX ; Занесение
номера в FCB
026F 8D 16 005C R
LEA DX, FCB
0273 B4 21 MOV AH, 21H
; Прямое чтение записи
0275 CD 21 INT
21H
Фиг. 5.6 Пример использования функциямй DOS (продолжение)
0277 0A C0 OR AL, AL
; Проверка на ошибку
0279 74 07 JE
RANDOM_RECORD_OK
027B 8D 16 0153 R
LEA DX, BAD_READ_MSG
; Сообщение об ошибке
027F E9 01E5 R JMP ERROR_EXIT
;-----
Вывод старой записи на экран
0282 RANDOM_RECORD_OK:
0282 C6 06 00B0 R 0A
MOV DISK_TRANSFER_ADDRESS+32,
10 ; Занесение символов конца
0287 C6 06 00B1 R 0D
MOV DISK_TRANSFER_ADDRESS+33,
13 ;
строки и конца вывода
028C C6 06 00B2 R 24
MOV DISK_TRANSFER_ADDRESS+34,
'$' ;
в буфер
0291 B4 09 MOV AH, 9H
0293 8D 16 0090 R
LEA DX, DISK_TRANSFER_ADDRESS
0297 CD 21 INT 21H
; Вывод записи на экран
;-----
Изменение файла
0299 A0 0106 R MOV AL,
KEYBOARD_BUFFER+3 ; Выборка символа,
на который будет
029C B9 001F MOV CX,
RECORD_SIZE-1 ; заменяться содержимое записи
029F 8D 3E 0091 R
LEA DI,
DISK_TRANSFER_ADDRESS+1
02A3 F3/ AA REP STOSB
; Замена 31 символа
02A5 B4 22 MOV AH, 22H
02A7 8D 16 005C R
LEA DX, FCB
02AB CD 21 INT 21H
; Прямая запись на файла на
;
старое место
02AD 0A C0 OR AL, AL
; Проверка на ошибку
02AF 74 07 JZ
RANDOM_WRITE_OK
02B1 8D 16 0138 R
LEA DX, BAD_WRITE_MSG ; Сообщение об ошибке
02B5 E9 01E5 R JMP ERROR_EXIT
02B8 RANDOM_WRITE_OK:
02B8 E9 0239 R JMP KEYBOARD_LOOP
; Обработка следующей записи
;-----
Конец программы
02BB PROGRAM_EXIT:
02BB B4 10 MOV AH, 10H
; Закрытие файла
02BD 8D 16 005C R
LEA DX, FCB
02C1 CD 21 INT 21H
02C3 0A C0 OR AL, AL
; Проверка на ошибку
02C5 74 07 JZ CLOSE_OK
02C7 8D 16 016D R
LEA DX, BAD_CLOSE_MSG ; Сообщение об ошибке
02CB E9 01E5 R JMP ERROR_EXIT
02CE CLOSE_OK:
02CE CD 20 INT 20H
; Возврат в ДОС
02D0 CODE
ENDS
END
Фиг. 5.6 Пример использования
функциямй DOS (продолжение)
Приведенная программа состоит из двух
частей. В первой части
создается файл из 26 записей длиной по 32
байта. Каждая запись
соответствует одной букве алфавита: запись
1 - это "AAAA...A",
запись 2 - "BBBB...B" и т.д.
Данный файл формируется
последовательно. Во второй части программы
этот файл
Mincho"'> рассматривается как файл с произвольным
доступом. В ответ на
введенный пользователем с клавиатуры
запрос программа считывает и
выводит на дисплей одну из 26 записей. С
помощью этого же ввода
осущкствляется редактирование записи: 31
символ записи, начиная со
второго, заменяется на значение, которое
вводится с клавиатуры.
Выполнение программы завершается при вводе
с клавиатуры символа
"$".
В этом примере моделируется справочная
база данных. На первом
этапе программа осуществляет формирование
этой базы данных. На
втором этапе выполняется обработка
произвольных запросов к базе
данных и редактирование ее содержимого.
Хотя любая реальная
программа управления базой данных гораздо
сложнее, чем приведенный
здесь пример, однако он является хорошей
иллюстрацией основных
функций, относящихся к работе с файлами.
Программа, приведенная на Фиг. 5.6, - это
файл типа .COM. В
следующем разделе мы обсудим различие
между этим файлом и файлом
типа .EXE. Использование в данном примере
файла типа .COM позволяет
для завершения работы программы
воспользоваться прерыванием INT
20H. В случае файла типа .COM начало
программы в сегменте должно
иметь смещение 100H. Первые 100H байт
программного сегмента
называются программным префиксом PSP и
предназначены для хранения
некоторых специальных данных, которые
используются программной,
написанной на языке ассемблера.
Смещение блока FCB в сегменте равно 05CH,
и использование в
программе этого на первый взгляд
произвольного адреса имеет
определенные основания. Запись информации
в данный блок FCB
осуществляется командным процессором,
входящим в состав DOS. После
того, как пользователь вызвал программу,
указав ее имя, DOS
просматривает оставшуюся часть командной
строки в поисках имен
файлов. Первое встретившееся в команде имя
помещается в блок FCB,
смещение которого равно 05CH. Если в
командной строке будет еще
одно имя, то оно запишется в блок FCB со
смещением 06CH. Так как в
нашеи примере фигурирует только один файл,
то используют только
блок FCB со смещением 05CH. Запуск
описываемой программы
осуществляется с помощью следующей
синтаксической конструкции:
A> FIG5=6 TEST.FIL
FIG5=6 - имя программы. В каталоге
программа фигурирует под
именем FIG5=6.COM. Файл TEST.FIL является
файлом, который программа
создает и затем модифицирует.
Интерпретатор командных строк
выбирает имя "TEST.FIL" и
помещает его в соответствующее поле блока
FCB со смещением 05CH. Рассматривая имя
файла в качестве параметра
командной строки, можно с помощью
описываемой программы создавать и
модифицировать любой файл. Если бы имя
файла входило в ассемблерную
программу, мы могли бы работать только с
единственным файлом.
Начиная со смещения 05CH, текст программы
соответствует
структуре блока FCB. Первая ячейка
идентифицируется меткой блока
FCB. Каждое из полей FCB имеет свою метку
и длину, так что
программа может обрабатывать их непосредственно.
Например, чтобы
задать длину записи, программа
модифицирует переменную
FCB_RECORD_SIZE.
Начиная с адреса 080H помещается еще одно
специальное поле
программного префикса. Эта область памяти
размером 128 байт
отводится по умолчанию под область связи с
диском DTA (Disk
Transfer Area) и используется DOS в
качестве буфера для всех
файловых записей. Всякий раз, записывая
или читая запись, DOS
использует буфер области DTA. Во время
инициализации DOS
устанавливает смещение области DTA в
программном сегменте равным
080H. Программа может изменить это
значение, используя функцию 1AH
прерывания 21H. Это смещение должно быть
изменено, еслм длина
записи больше, чем 128 байт. В
рассматриваемом примере область
связи с диском сдвигается до смещения в
сегменте, равного 90H. Это
связано с тем, что блок FCB со смещением
05CH выходит за границу с
адресом 80H. Если бы граница области DTA
определялась соглашением,
принятым по умолчанию, то при передаче
файлов информация в
последнем байте блока FCB была бы
разрушена. В этом байте
записывается номер записи при произвольном
доступе к файлу. Так как
в данной программе для чтения-записи
данных используется
произвольный доступ, упомянутое наложение
информации необходимо
исключить.
Первая команда программы имеет смещение
100H и является
переходом на фактическое начало программы.
Такая структура
программы может показаться неэффективной,
однако ассемблирование
происходит гораздо успешней, если все
данные помещаются перед
командами, которые на них ссылаются.
Фактически в программе могут
быть ошибки, если она содержит ссылки на
данные вперед. Поэтому для
большей надежности данные помещаются в
начале программы.
В первой части программы устанавливается
область связи с
диском. В данной программе эта буферная
область имеет смещение 90H.
Так как длина записи равняется только 32
байтам, то впереди
программы имется достаточно места.
Далее в программе используется прерывание
21H и функция DOS для
поиска файла с именем, совпадающим с
именем, записанным в блоке
FCB. Обратите внимание, что пара регистров
DC:DX указывает на блок
FCB, как и должно быть при любых файловых
операциях. Если система
обнаружит файл с идентичным именем,
программа завершит работу,
выдав сообщение об ошибке и сохранив
существующий уже файл. В
данной программе обрабатываются только
новые файлы. Существующие
файлы здесь никак не используются, однако
гарантируется, что их
содержимое программой не сотрется.
Конечно, в реальной практике
програма была бы составлена так, чтобы
охватывать случай как новых,
так и уже существующих файлов.
Создание файла обеспечивается участком
программы, помещенным
NO_FILE. Формировать блок FCB до этого
данной программе не нужно,
так как он был сформирован командным
процессором. Если описываемая
файловая операция не сможет быть
выполнена, например, из-за
отсутствия свободного места на диске или
отсутствия места в
каталоге диска, то программа завершит
выполнение и выдаст
соответствующее сообщение об ошибке.
При любом обращении DOS к файлу программа
должна, прежде всего,
открыть файл. Процедура открытия файла
устанавливает связь между
операционной системой и пользовательской
программой. В процессе
этой операции DOS просматривает справочник
диска, находит нужный
файл (или не находит, что соответствует
сбойной ситуации) и
заполняет поле блока FCB, относящееся к
длине файла. После того,
как файл открыт, DOS не должна
просматривать справочник диска
всякий раз, когда происходит обращение к
файлу. Система DOS
сохраняет в блоке FCB информацию о файле
до тех пор, пока она этот
файл не "закроет". Термины
"закрыть" и "открыть" файл еще раз
указывают на связь с традиционным
делопроизводством. Папку с файлом
документов нужно открыть прежде, чем можно
будет ознакомиться с
содержащимся в ней бумагами, и закрыть до
того, как ее уберут снова
в бюро.
В рассматриваемом примере открытие файла
происходит при его
создании. Если бы такой файл уже
существовал, связь с ним была бы
установлена с помощью функции открытия
файла (AH=0FH). Если
открытие файла произошло успешно,
программма изменяет значения
некоторых полей блока FCB. В частности,
длина записи должна быть
установлена равной 32 байт, так как по
умолчанию DOS считает ее
равной 128 байт.
Часть программы с именем CHARACTER_LOOP
передает в файл 26
записей. Определяющий символ каждой записи
передается в буфер
области DTA оператором REP STOSB.
Отдельные записи передаются на
диск с помощью функции последовательной
записи (AH=0AH). Программа
также выполняет проверку на отсутствие
ошибок.
Начиная с метки KEYBOARD_LOOP программа
переходит от
формирования файла к запросу=коррекции
записей в нем. В данном
примере используется буферированный ввод с
клавиатуры,
поддерживаемый DOS. Это позволяет
пользователю вводить строку из
двух символов и, если необходимо,
осуществлять редактирование.
После ввода двух символов должна быть
нажата клавиша окончания
ввода. Программа выполняет проверку
правильности ввода, и если
последний не удовлетворяет требованиям, то
он отвергается и
выдается сообщение об ошибке.
При вводе пользователем символа
"$" программа заканчивает
работу. В случае же ввода символов от
"A" до "Z" программа
осуществляет чтение соответствующей записи
и выводит на дисплей ее
содержимое. В оставшиеся 31 байт буфера
программа записывает второй
из введенных с клавиатуры символов.
Модицифированная таким образом
запись передается на диск в режиме
произвольного доступа.
В заключительной части программы
осуществляется закрытие файла.
Аналогично тому, как функция открытия
файла устанавливала связь
между DOS и пользовательской программой,
??????
файла существенно для гарантии того, что
DOS записала на диск все
модифицированные записи. Во время
нормального выполнения программы
DOS может оставить несколько последних
записей в буфере. Это
ускоряет выполнение, так как DOS не должна
обращаться к диску по
поводу каждой записи. Функция закрытия
файла осуществляет запись на
диск содержимого буфера.
Приведенный на Фиг. 5.6 пример программы
иллюстрирует основные
способы обращения к файлу с помощью DOS.
Эта программа ничего
полезного не выполняет, однако приближение
ее к реальным задачам
потребовало бы намного большего числа
команд, которые мало что
прояснили бы в отношении использования
функций DOS. В данной
программе важно обратить внимание на
необходимость проверки ошибок
после каждой операции, выполняемой DOS. В
то время, как DOS с
помощью прерывания 24H обрабатывает
аппаратные ошибки,
пользовательская программа должна разрешать
такие ситуации, как
совпадение имен файлов или отсутствие
свободного места на дискете.
В данном примере обработка ошибок проста и
состоит из вывода
соответствующего сообщения и завершения
работ программы. Обработка
ошибок в реальных программах значительно
сложнее и более актуальна,
так как в этом случае возможность потери
важной информации должна
быть исключена.
И наконец, возможно, что проработав с
данной программой, вы
будете не очень удовлетворены ею как пользователь:
в ней
отсутствует запрос на ввод данных,
сообщения об ошибках лаконичны и
некоторые из выводимых сообщений частично
накладываются на
предыдущие, затирая их. Данная программа
нуждается в доработке
прежде, чем ею сможет воспользоваться
кто-либо, не участвовавший в
ее написании или тщательно в ней не
разобравшийся.