Страница 10 из 41
5.2.3 Чтение/изменение подкаталога. Подкаталоги во многом подобны корневому каталогу, за исключе- нием того, что они хранятся как обычные файлы, а не в заранее предопределенных секторах. Подкаталоги невозможно спутать с обыч- ными файлами, поскольку объект каталога, относящийся к подкатало- гу, имеет специальный байт атрибутов (с установленным битом 5 - см. [5.2.6]). Подкаталоги начинаются с двух специальных 32-байт- ных объектов, первый из которых имеет имя точка, а второй - две точки. Они ориентируют подкаталог среди окружающих каталогов. Ссылки на подкаталоги нижнего уровня записываются как обычные ссылки на файлы. Предполагается, что подкаталог может быть прочитан как любой другой файл, поэтому вроде бы не составляет труда загрузить его в память. Но, к сожалению, создатели MS DOS поместили 0 в поле длины файла для элементов, относящихся к подкаталогам. В резуль- тате DOS считает, что этот файл имеет нулевую длину и отказывает- ся читать его. Нет простого способа преодолеть эту проблему.
Высокий уровень. В Бейсике команда FILES может использовать стандартные имена путей для вывода подкаталога; например, FILES "B:MAMMALS\BIRDS"
выводит все файлы, содержащиеся в подкаталоге BIRDS. Эта команда может быть использована и для получения информации о наличии в каталоге определенного файла. Например, FILES "LEVEL1\NEWDATA" ищет файл NEWDATA и выводит его имя, если он найден. Хотя это может быть полезным для пользователя, но часто самой программе необходимо знать существует или нет указанный файл. Чтобы устано- вить это попытайтесь открыть файл для последовательного чтения. Если он не будет найден, то возникнет ошибочное условие 63. Соз- дайте процедуру обработки ошибок, как описано в [5.4.8]. Затем используйте переменную, чтобы отметить был ли найден требуемый файл (в нашем примере переменная "EXISTS"). Если программе не нужно, что этот файл был открыт, то закройте его перед тем как двинуться дальше.
100 ON ERROR GOTO 1000 'процедура обработки ошибок 110 EXISTS = 1 'начальное значение "флага" 120 INPUT "Enter filename: ",S$ 'запрос имени файла 130 OPEN S$ FOR INPUT AS #3 'открываем его для послед. чтения 140 IF EXISTS = 0 THEN BEEP: PRINT "File does not exist" . . 1000 IF ERR = 53 THEN 1500 'файл не существует? 1010 IF ERR = 64 THEN ... 'другие ошибки . 1500 EXISTS = 0 'меняем значение флага 1510 RESUME 140 'продолжаем выполнение программы
Средний уровень. Функции работы через дескрипторы файлов, которые использова- лись для доступа к корневому каталогу [5.2.1] могут так же просто обращаться к любому подкаталогу. Чтобы вывести все содержимое каталога надо просто использовать функцию 4EH для поиска файлов *.*, а затем повторять поиск, используя функцию 4FH. Когда больше не будет файлов, то будет установлен флаг переноса, а AL будет
содержать 18. Каждый раз, когда будет обнаружен очередной эле- мент, в DTA будет записана информация о файле, включая полный его путь (отмечаем использование DTA в функциях, использующих деск- риптор файла). Следующий пример выводит полные пути всех обычных файлов подкаталога.
;---в сегменте данных PATH DB 'A:MAMMALS\*.*',0 DTAH DB 256 DUP(?)
;---установка DTA LEA DX,DTA ;DS:DX указывают на DTA MOV AH,1AH ;функция установки DTA INT 21H ;устанавливаем DTA
;---ищем первый файл MOV AH,4EH ;номер функции LEA DX,PATH ;указываем на строку пути MOV CX,0 ;только нормальные атрибуты INT 21H ;ищем *.* JC ERROR ;обработка ошибок ;---выводим имя файла NEXT_LINE: LEA BX,DTA ;BX указывает на DTA ADD BX,30 ;смещение для имени файла NEXT_CHAR: MOV DL,[BX] ;получаем символ из имени CMP DL,0 ;проверка на конец строки JE END_STR ;уход, если конец MOV AH,2 ;иначе, выодим символ INT 21H ; INC BX ;увеличиваем указатель JMP SHORT NEXT_CHAR ;следующий символ ;---возврат каретки/перевод строки в конце строки END_STR: MOV AH,2 ;функция вывода символа MOV DL,13 ;код возврата каретки INT 21H ;выводим MOV DL,10 ;код перевода строки INT 21H ;выводим ;---ищем следующий файл LEA DX,PATH ;указываем на строку пути MOV AH,4FH ;номер функции INT 21H ;ищем следующий файл JC FINISHED ;если нет, то выход JMP SHORT NEXT_LINE ;иначе выводим имя файла FINISHED:
|