Работа с файлами в DOS

Автор: xrnd | Рубрика: Исходники | 25-12-2010 | Распечатать запись Распечатать запись

Эта статья лишь небольшой пример того, как можно работать с файлами, используя функции DOS. Я не буду описывать все возможные значения параметров и вдаваться в подробности. Это вы можете найти самостоятельно в справочнике.

Первая программа будет создавать файл и записывать в него данные. Вторая программа — открывать файл, читать данные и выводить их на консоль.

Создание нового файла

Прежде, чем что-то записывать, необходимо создать файл. Для этого используется функция DOS 3Ch.

Имя файла должно быть в формате 8.3 — 8 символов имени и 3 символа расширения. Естественно, можно использовать только английский буквы, цифры и некоторые другие символы. Строка с именем файла должна заканчиваться нулевым байтом. Если файл уже существует, то его содержимое будет удалено.

Об ошибке можно узнать, проверяя значение флага CF (1 — ошибка, 0 — нет ошибки). Аналогично для других функций работы с файлами. Если флаг CF равен 0, то в регистре AX будет находиться дескриптор (или описатель) файла. Дескриптор — это просто специальное число, по которому операционная система отличает один открытый файл от другого.

Запись данных в файл

Запись в файл выполняется функцией DOS 40h. Этой функции нужно передать в регистре BX тот самый дескриптор, который был получен при создании файла.

Если вам требуется записать много данных, можно вызывать эту функцию несколько раз.

Закрытие файла

После работы с файлом нужно его закрыть с помощью функции DOS 3Eh.

Если вы не закроете файл, то он будет закрыт системой при выходе из программы. Однако, хорошим стилем программирования является явное закрытие файла после завершения работы с ним.

Пример первый

Программа создаёт новый файл и записывает в него данные. Так как диск и директория не указаны, то файл создаётся в текущей папке. В данном примере в файл записываются 2 строки, получается текстовый файл. Можно работать с двоичными файлами, записывая любые байты, слова и т.д.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
use16                       ;Генерировать 16-битный код
org 100h                    ;Программа начинается с адреса 100h
    jmp start               ;Перепрыгнуть данные
;-------------------------------------------------------------------------------
; Данные
file_name db 'hello.txt',0
buffer    db 'asmworld.ru',13,10,'Hello!'
size      db 19
s_error   db 'Error!',13,10,'$'
s_pak     db 'Press any key...$'
handle    rw 1              ;Дескриптор файла
;-------------------------------------------------------------------------------
; Код
start:
    mov ah,3Ch              ;Функция DOS 3Ch (создание файла)
    mov dx,file_name        ;Имя файла
    xor cx,cx               ;Нет атрибутов - обычный файл
    int 21h                 ;Обращение к функции DOS
    jnc @F                  ;Если нет ошибки, то продолжаем
    call error_msg          ;Иначе вывод сообщения об ошибке
    jmp exit                ;Выход из программы
@@: mov [handle],ax         ;Сохранение дескриптора файла
 
    mov bx,ax               ;Дескриптор файла
    mov ah,40h              ;Функция DOS 40h (запись в файл)
    mov dx,buffer           ;Адрес буфера с данными
    movzx cx,[size]         ;Размер данных
    int 21h                 ;Обращение к функции DOS
    jnc close_file          ;Если нет ошибки, то закрыть файл
    call error_msg          ;Вывод сообщения об ошибке
 
close_file:
    mov ah,3Eh              ;Функция DOS 3Eh (закрытие файла)
    mov bx,[handle]         ;Дескриптор
    int 21h                 ;Обращение к функции DOS
    jnc exit                ;Если нет ошибки, то выход из программы
    call error_msg          ;Вывод сообщения об ошибке
 
exit:
    mov ah,9
    mov dx,s_pak
    int 21h                 ;Вывод строки 'Press any key...'
    mov ah,8                ;\
    int 21h                 ;/ Ввод символа без эха
    mov ax,4C00h            ;\
    int 21h                 ;/ Завершение программы
 
;-------------------------------------------------------------------------------
; Процедура вывода сообщения об ошибке
error_msg:
    mov ah,9
    mov dx,s_error
    int 21h                 ;Вывод сообщения об ошибке
    ret

В результате работы программы создаётся файл, который можно открыть блокнотом:

Открытие существующего файла

Для открытия файла используется функция DOS 3Dh. В отличие от создания файла, эта функция завершится ошибкой, если файл не существует.

Чтение данных из файла

Чтение из файла выполняется функцией DOS 3Fh.

Размер буфера для данных должен быть больше или равен количеству считываемых байтов. Обратите внимание, что в AX функция возвращает количество реально прочитанных байтов. Это количество может быть меньше требуемого, например, если файл слишком короткий.

Пример второй

Программа читает данные из текстового файла и выводит на консоль. Для того, чтобы вывести данные, нужно добавить символ ‘$’ в конец строки.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use16                       ;Генерировать 16-битный код
org 100h                    ;Программа начинается с адреса 100h
    jmp start               ;Перепрыгнуть данные
;-------------------------------------------------------------------------------
; Данные
file_name db 'hello.txt',0
s_error   db 'Error!',13,10,'$'
s_file    db '----[ file "Hello.txt" ]$'
endline   db 13,10,'$'
s_pak     db 'Press any key...$'
buffer    rb 81             ;80 + 1 байт для символа конца строки '$'
handle    rw 1              ;Дескриптор файла
;-------------------------------------------------------------------------------
; Код
start:
    mov ah,3Dh              ;Функция DOS 3Dh (открытие файла)
    xor al,al               ;Режим открытия - только чтение
    mov dx,file_name        ;Имя файла
    xor cx,cx               ;Нет атрибутов - обычный файл
    int 21h                 ;Обращение к функции DOS
    jnc @F                  ;Если нет ошибки, то продолжаем
    call error_msg          ;Иначе вывод сообщения об ошибке
    jmp exit                ;Выход из программы
@@: mov [handle],ax         ;Сохранение дескриптора файла
 
    mov bx,ax               ;Дескриптор файла
    mov ah,3Fh              ;Функция DOS 3Fh (чтение из файла)
    mov dx,buffer           ;Адрес буфера для данных
    mov cx,80               ;Максимальное кол-во читаемых байтов
    int 21h                 ;Обращение к функции DOS
    jnc @F                  ;Если нет ошибки, то продолжаем
    call error_msg          ;Вывод сообщения об ошибке
    jmp close_file          ;Закрыть файл и выйти из программы
 
@@: mov bx,buffer
    add bx,ax               ;В AX количество прочитанных байтов
    mov byte[bx],'$'        ;Добавление символа '$'
 
    mov ah,9
    mov dx,s_file
    int 21h                 ;Вывод строки с именем файла
 
    mov cx,56
    call line               ;Вывод линии
 
    mov ah,9
    mov dx,buffer
    int 21h                 ;Вывод содержимого файла
    mov dx,endline
    int 21h                 ;Вывод перехода на новую строку
 
    mov cx,80
    call line               ;Вывод линии
 
close_file:
    mov ah,3Eh              ;Функция DOS 3Eh (закрытие файла)
    mov bx,[handle]         ;Дескриптор
    int 21h                 ;Обращение к функции DOS
    jnc exit                ;Если нет ошибки, то выход из программы
    call error_msg          ;Вывод сообщения об ошибке
 
exit:
    mov ah,9
    mov dx,s_pak
    int 21h                 ;Вывод строки 'Press any key...'
    mov ah,8                ;\
    int 21h                 ;/ Ввод символа без эха
    mov ax,4C00h            ;\
    int 21h                 ;/ Завершение программы
 
;-------------------------------------------------------------------------------
; Процедура вывода сообщения об ошибке
error_msg:
    mov ah,9
    mov dx,s_error
    int 21h                 ;Вывод сообщения об ошибке
    ret
;-------------------------------------------------------------------------------
; Вывод линии
; CX - количество символов
line:
    mov ah,2                ;Функция DOS 02h (вывод символа)
    mov dl,'-'              ;Символ
@@: int 21h                 ;Обращение к функции DOS
    loop @B                 ;Команда цикла
    ret

Результат работы программы:

Некоторые другие функции DOS для работы с файлами

Подробное описание смотрите в справочнике.

  • 5Bh — создание нового файла без удаления существующего;
  • 5Ah — создание файла с уникальным именем (например, временного файла);
  • 41h — удаление файла;
  • 42h — установка указателя чтения/записи;
  • 56h — переименование файла;
  • 43h — получение или изменение атрибутов файла;
  • 57h — получение или изменение метки времени файла;
  • 39h — создание папки;
  • 3Ah — удаление папки;
  • 3Bh — изменение текущей папки;
  • 47h — получение текущей папки.

Комментарии: