JC CLOSE_ERROR ;уход на обработку ошибки
Функция 45H прерывания 21H создает второй дескриптор файла из
существующего открытого дескриптора. В BX должен быть указан
существующий номер, а в AX будет возвращен новый. Функция 46H
прерывания 21H связывает второй дескриптор (помещаемый в CX) с
открытым файлом (номер которого в BX) таким образом, что первый
будет относиться к тому же файлу и устройству, что и последний.
5.3.4 Переименование файла; изменение позиции файла в катало-
ге.
Переименование файла может заключаться лишь в изменении первых
11-ти символов элемента каталога. Однако в древовидном каталоге
весь элемент каталога может быть перенесен в другой подкаталог,
переопределяя тем самым путь к файлу. Одна команда может как
переименовать файл, так и перенести его в другой каталог.
Высокий уровень.
В Бейсике файл переименовывается командой NAME. С помощью этой
команды он может быть также перенесен в другой каталог. Hапишите
сначала существующее имя, а затем новое имя файла, оба заключен-
ные в кавычки, например NAME "OLDFILE.EXT" AS "NEWFILE.EXT". В
этом случае будет переименован файл в корневом каталоге. Для
изменения имен файлов, расположенных в подкаталогах, могут быть
использованы пути к файлу. Hапример, NAME "B:LEVEL1\OLDFILE.EXT"
AS "B:LEVEL1\NEWFILE.EXT" изменяет имя файла в подкаталоге LE-
VEL1.
Отметим, что для нового имени файла должен быть указан полный
путь. Если Вы запишете NAME "B:LEVEL1\OLDFILE.EXT" AS "NEWFI-
LE.EXT", то файл будет не только переименован, но и перенесен в
корневой каталог. Для переноса файла из одного подкаталога в
другой без изменения его имени напишите команду NAME "A:SUBDIR1-
\OLDFILE.EXT" AS "A:SUBDIR2\OLDFILE.EXT". Таким методом нельзя
перенести файл с диска на диск. Поскольку файлы, расположенные в
разных каталогах могут иметь одно и то же имя, то возможна ошибка
при попытке переноса файлов с одинаковыми именами. В этом случае
будет возвращен код ошибки 58 [5.4.8].
Средний уровень.
MS DOS может переименовывать файлы, используя как метод управ-
ляющего блока файла, так и метод дескриптора файла. Первый из них
может применяться только к файлам, расположенным в текущем ката-
логе.
Метод FCB:
Используйте функцию 17H прерывания 21H. DS:DX должны указывать
на открытый управляющий блок файла. Поместите новое имя файла в
FCB, начиная со смещения 11H (это "резервная" область блока).
Hовое имя может использовать символ "?", в этом случае символы,
находящиеся в этих позициях, не будут изменяться. При возврате,
если новое имя уже существовало в каталоге, то AL будет равно FF,
иначе AL = 0. В примере имя файла ACCOUNTS.DAT меняется на
DEBTS.DAT.
;---в сегменте данных
FCB DB 'FILENAMEEXT',25 DUP(0)
NEWNAME DB 'NEWNAME EXT', ;11 символов нового имени
;---помещаем новое имя файла в переменную NEWNAME
MOV SI,OFFSET NEWNAME ;DS:SI указывают на новое имя
MOV AX,SEG FCB ;ES:DI указывают на FCB
MOV ES,AX ;
MOV DI,OFFSET FCB ;
ADD DI,11H ;начинаем со смещения 11H
MOV CX,11 ;имя файла содержит 11 символов
REP MOVSB ;переносим 11 байтов
LEA DX,FCB ;DS:DX указывают на FCB
MOV AH,17H ;функция изменения имени
INT 21H ;изменяем имя
CMP AL,0FFH ;проверка на ошибку
JE RENAME_ERROR ;уход на обработку ошибки
Метод дескриптора файла:
Функция 56H прерывания 21H переименовывает и перемещает файлы.
DS:DX должны указывать на строку, дающую путь и имя переименуемо-
го файла (до 63-х символов) и завершающуюся символом ASCII 0.
ES:DI должны указывать на вторую строку, которая дает новые имя и
путь файла. Имена накопителей, если они присутствуют, должны
совпадать. Если пути различны, то файл переноносится в другой
подкаталог. Чтобы перенести файл без переименования надо во вто-
рой строке указать то же самое имя, но другой путь. При возврате,
если произошла ошибка, то устанавливается флаг переноса, а AX
будет содержать 3 - если один из путей не найден, 5 - при ошибке
на диске и 17 - при попытке переноса между разными накопителями.
В примере файл ACCOUNTS.DAT переносится из подкаталога GAINS в
подкаталог LOSSES.
;---в сегменте данных
OLDPATH DB 'A:GAINS\ACCOUNTS.DAT',0
NEWPATH DB 'A:LOSSES\ACCOUNTS.DAT',0
;---изменение пути файла
LEA DX,OLDPATH ;DS:DX указывают на старый путь
MOV AX,SEG NEWPATH ;ES:DI указывают на новый путь
MOV ES,AX ;
MOV DI,OFFSET NEWPATH ;
MOV AH,56H ;номер функции
INT 21H ;переносим файл
JC ERROR_ROUTINE ;уход на обработку ошибки
5.3.5 Подготовка к файловым операциям.
Языки высокого уровня, такие как Бейсик, выполняют подготови-
тельную работу для файловых операций автоматически. Однако прог-
раммы на языке ассемблера имеют достаточно работы перед тем как
создать или открыть файл. Требования отличаются, в зависимости от
того используется ли для доступа к файлу метод управляющего блока
файла или метод дескриптора файла. Для обоих методов Вам необхо-
димо строку или блок параметров, указывающих на файл и буфер для
переноса данных. MS DOS предоставляет различные наборы функций
чтения/записи для двух методов.
Средний уровень.
Метод управляющего блока файла:
Этот метод доступа к файлам требует, чтобы Вы создали блок
параметров, котрый первоначально должен содержать такую информа-
цию, которая позволяет найти файл в каталоге. Хотя FCB имеет
много полей, вообще говоря, только некоторые из них должны быть
заполнены; MS DOS заполняет большинство остальных полей информа-
цией после того, как файл открывается. Отметим, что к началу FCB
может добавляться специальное поле для создания расширенного FCB,
который объяняется ниже. Вот структура FCB:
Hакопитель (DB) Число, определяющее на каком накопителе
будет искаться файл, 1 = A, 2 = B и т.д.
Если указан 0, то берется накопитель по
умолчанию, а затем система заменяет 0 на код
этого накопителя.
Имя и расширение Восьмибайтное имя файла, выравненное по
(11 байтов) левому краю должно быть дополнено пробелами
(ASCII 32), если оно меньше 8 байтов. То же
относится и к трехбайтному расширению. Между
ними не должна стоять точка.
Текущий блок (DW) DOS организует файлы блоками по 128 записей,
пронумерованных от 0 до 127. Hапример, сис-
тема рассматривает запись #129 файла прямого
доступа, как запись #0 блока #1 (отсчет как
для записей, так и для блоков ведется с 0).
В файлах нет специальных ограничителей ни
для блоков ни для записей. Вместо этого
смещение для блоков и записей вычисляется
исходя из длины записи, которая устанавли-
вается следующим полем FCB.
Размер записи (DW) Все функции MS DOS, связанные с чтением или
записью в файл, работают в терминах записи.
Для файлов прямого доступа важно, чтобы
размер записи был установлен равным размеру
записей, помещенных в файл. Для последова-
тельных файлов размер записи не столь важен,
однако маленький размер записи будет замед-
лять дисковые операции. Поскольку размер
сектора 512 байтов, то оптимальным является
размер записи 512 байтов. Система автомати-
чески помещает значение по умолчанию 80H
(128) в поле длины записи при открытии фай-
ла. Поэтому не забудьте установить это поле
после открытия файла.
Размер файла (DD) Размер указывается с точностью до байта. Это
поле заполняется системой при открытии фай-
ла.
Дата файла (DW) Дата записывается системой при открытии FCB.
Ее формат приведен в [5.2.5].
Текущая запись (DB) Текущая запись используется совместно с
полем текущего блока. Записи нумеруются от 0
до 127. Запись прямого доступа #200, распо-
ложенная в блоке 1, имеет номер текущей
записи равный 71 ((200 - 128) - 1).
Hомер записи пря- Вместо того, чтобы требовать от программы,
мого доступа (DD) чтобы она вычисляла текущие значения блока и
записи для файла прямого доступа, MS DOS
делает эту работу сама. При операциях с
файлами прямого доступа просто поместите
номер записи в это 4-хбайтное поле. При
выполнении операции с файлом прямого доступа
MS DOS поместит нужные значения в поля теку-
щего блока и текущей записи. Помните, что
старший байт расположен в старшей ячейке.
Связь между полями текущей записи, текущего блока и номер записи
прямого доступа показана на рис. 5-3.
Простейший путь создать FCB как переменную в сегменте данных
программы. Если имя открываемого файла не меняется, то это имя
может быть прямо записано в это поле. Остаток блока инициализи-
руйте байтами ASCII 0. Только после того как FCB будет открыт (с
помощью функции 0FH прерывания 21H, как показано в [5.3.3]) Вы
должны записать в блок остальную информацию. Отметим, что FCB для
работы с простым последовательным файлом с длиной записи 128
байтов не требует дальнейших приготовлений. После создания FCB
дальнейшие операции требуют, чтобы DS:DX указывали на него. Прос-
тейшая форма его такая:
FCB DB 1,'FILENAMEEXT',25 DUP(0)
Можно также создать FCB как структуру:
FCB STRUC
DRIVE_NUM DB 0
FILE_NAME DB 8 DUP(?)
FILE_EXT DB 3 DUP(?)
BLOCK_NUM DW 0
RECORD_SIZE DW 0
FILE_SIZE DD 0
FILE_DATE DW 0
RESERVED DB 10 DUP(0)
CURRENT_REC DB 0
RANDOM_REC DD 0
FCB ENDS
При таком подходе программе проще помещать данные в FCB, посколь-
ку метки существуют для каждого поля. В зависимости от типа фай-
ловых операций на поля могут накладываться следующие ограничения:
1. Для файлов прямого доступа Вы должны установить размер
записи и номер записи в поле записи прямого доступа.
2. Для доступа к последовательным файлам с начала Вы должны
установить только размер записи, при условии, что Вы инициализи-
ровали поля текущего блока и текущей записи в 0 (просто обнулите
весь FCB, за исключением имен накопителя и файла). При открытии
поле размера записи будет установлено равным 128, если это значе-
ние устаривает Вас, то дальнейшая подготовка не нужна.
3. Для доступа к последовательному файлу с середины или с
конца Вы должны установить поля текущего блока и текущей записи
(в этом случае Ваша программа должна будет производить вычисления
сама).
Префикс программного сегмента [1.3.0] имеет достаточно большое
поле, чтобы содержать управляющий блок файла. Это пространство
предоставляется для каждой программы, поэтому экономно использо-
вать его, особенно в программах типа .COM. Поле FCB расположено
со смещением 5CH в префиксе программного сегмента. В программах
COM используйте ORG для создания FCB следующим образом (здесь