Днепропетровский национальный университет железнодорожного транспорта имени академика
В. Лазаряна
Кафедра КИТ
Отчет
С лабораторной работы № 1
По теме: " Работа с файлами с помощью дескрипторов "
Выполнил
Студент
926 группы
Попов Д.Ю.
Проверила
Разумов С.Ю.
Днепропетровск
- Мета роботи:
Разработать программу для обработки файлов. В программе следует предусмотреть следующие операции:
- Создание файла занесения в него информации, которую пользователь вводит с клавиатуры;
- Обработка файла с индивидуальным заданием и запись результатов обработки в новый файл;
- Чтение файлов и вывод информации из файлов на экран монитора;
Подсчитать количество символов в каждой строке файла.
- Индивидуальное задание:
Подсчитать количество символов в каждой строке файла.
- Теория:
Работа с дескрипторами файлов
Дескриптор файла - это целое число без знака, с помощью которого процесс обращается к открытому файлу. В каждом процессе может быть выделено до двух тысяч дескрипторов. Они создаются при выполнении функций open, pipe, creat и fcntl. Обычно каждый процесс работает с уникальным набором дескрипторов. Однако эти же дескрипторы могут применяться и дочерними процессами, созданными с помощью функции fork. Кроме того, дескрипторы можно скопировать с помощью функций fcntl, dup и dup2.
Дескрипторы файлов выполняют роль индексов таблицы дескрипторов, которая расположена в области u_block и создается ядром для каждого процесса. Чаще всего процесс получает дескрипторы с помощью операций open и creat, а также путем наследования от родительского процесса. При выполнении операции fork таблица дескрипторов копируется для дочернего процесса. В результате дочерний процесс получает право обращаться к файлам родительского процесса.
Назначение и содержание
Преобразует индексы таблицы (дескрипторы файлов) в указатели на открытые файлы. Для каждого процесса в области u_block создается своя собственная таблица дескрипторов. Каждая запись такой таблицы содержит два поля: поле флагов и указатель на файл. Ниже описана структура таблицы дескрипторов:
struct ufd
{
struct file *fp;
int flags;
}u_ufd[OPEN_MAX]
Функция fcntl позволяет установить флаг FD_CLOEXEC в записи таблицы дескрипторов. Функция dup копирует запись о дескрипторе файла в другую строку этой же таблицы. При выполнении функции fork для дочернего процесса создается копия всей таблицы дескрипторов файлов.
Содержит записи с информацией обо всех открытых файлах. Два наиболее важных поля в записях этой таблицы - это текущее положение указателя в файле, на который ссылаются все операции чтения и записи, а также режим открытия файла (O_RDONLY, O_WRONLY или O_RDWR).
Ограничение на число дескрипторов файлов
Максимальное число дескрипторов, которое может использоваться в одном процессе, ограничено. Значение по умолчанию устанавливается в файле /etc/security/limits и обычно равно 2000 (для совместимости с предыдущими выпусками). Для изменения ограничения можно воспользоваться командой ulimit или функцией setrlimit. Максимальное число определяется константой OPEN_MAX.
Стандартные дескрипторы файлов
При запуске программы в оболочке открывается три дескриптора 0, 1 и 2. По умолчанию с ними связаны следующие файлы:
0 Стандартный ввод.
1 Стандартный вывод.
2 Стандартный вывод сообщений об ошибках.
Перечисленные дескрипторы файлов связаны с терминалом. Это означает, что при чтении данных из файла с дескриптором 0 программа получает ввод с терминала, а при записи данных в файлы с дескрипторами 1 и 2 они выводятся на терминал. При открытии других файлов дескрипторы присваиваются в порядке возрастания.
Если ввод-вывод перенаправляется с помощью операторов < (знак меньше) или > (знак больше), то стандартные дескрипторы связываются с другими файлами. Например, при выполнении команды:
prog < FileX > FileY
стандартные дескрипторы файлов 0 и 1 связываются с указанными файлами. В данном примере дескриптор 0 будет связан с файлом FileX, а дескриптор 1 - с файлом FileY. Дескриптор 2 не будет изменен. Программе достаточно знать, что дескриптор 0 представляет файл ввода, а дескрипторы 1 и 2 - файлы вывода. Информация о том, с какими конкретно файлами связаны эти дескрипторы, ей не нужна.
4. Листинг программы:
sseg segment para stack 'stack'
dw 80 dup(?)
sseg ends
;----------------------------------------------------------
dseg segment 'data'
strout1 db 'vvedit ryadok',13,10,'$'
strout2 db 'symvoliv v ryadku: ','$'
strout3 db '------[vyvid informacii]------',13,10,'$'
crlf db 13,10,'$'
buff db 80,?, 80 DUP(' ')
buflen equ 80
stdout equ 1
filename db 'file1.txt',0
err1 db 'oshibka 3Ch',13,10,'$'
handle dw?
bytesinstr db 3 DUP(?),'$'
dseg ends
; ---------------------------------------------------------
cseg segment 'code'
assume cs:cseg, ds:dseg, ss:sseg, es:dseg
start: mov ax,dseg
mov ds,ax
mov es,ax
mov ah,3ch;создать файл
mov cx,0;без атрибутов
mov dx,offset filename;адрес имени файла
int 21h
mov handle,ax;сохраним дескриптор файла
jnc inputstr;при ошибке устанавливается флаг CF
mov ah,9
lea dx,err1;выдать сообщение об ошибке
int 21h
jmp endprg
inputstr:;Ввод с клавиатуры
mov ah,9
lea dx,strout1;приглашение ввести текст
int 21h
mov ah,0ah;Функция ввод строки
lea dx,buff;адрес буфера для текста
int 21h
mov bh,0
mov bl,byte ptr [buff+1];длину строки в BL
cmp bl,0;Прервать если строка пустая
je closehndl;то закончить ввод
add bl,offset buff+2
mov byte ptr[bx],' ';Заменить символ CR на пробел
mov ah,9
lea dx,crlf;переход на новую строку экрана
int 21h
fop1:;Запись в файл
mov ah,40h;Функция записи
mov bx,handle;Указать дескриптор
mov cx,buflen;Длина записи
mov dx,offset buff+2;данные строки
int 21h
mov al,' ';20h;Символы заполнения строки
mov di,offset buff+2;адрес буфера
mov cx,buflen;размер буфера
cld;направление вперед(сбрость DF)
rep stosb;Очистить строку
jmp inputstr;ввести следующую строку
closehndl:;Закрыть файл
mov ah,3eh;функция закрытия
mov bx,handle;дескриптор
int 21h
mov ah,9
lea dx,crlf
int 21h
mov ah,9
lea dx,strout3
int 21h
call ReadFile;Считать данные из файла
endprg:
mov ah,4Ch; вернуться в dos
int 21h
;Чтение данных из файла
ReadFile proc near
mov ah,3Dh;функция открытия файла
mov al,2;доступ для чтения/записи
mov dx,offset filename
int 21h
mov handle,ax;запомнить дескриптор
readrec:
mov ah,3fh;Читать из файла
mov bx,handle;дескриптор
mov cx,buflen;столько читать
mov dx,offset buff+2;сюда
int 21h
cmp ax,0
je closehndl1;Прервать если прочитано 0 байт
mov cx,ax;столько прочитали
mov ah,40h;Записать в файл или устройство
mov bx,stdout;стандартный вывод (CON)
mov dx,offset buff+2;адрес строки,считанной из файла
int 21h
mov ah,40h
mov bx,stdout
mov cx,2
mov dx,offset crlf;вывести переход на новую строку
int 21h
call Variant4;вызвать обработчик строки
jmp readrec;прочесть следующую запись из файла
closehndl1:;Закрыть файл
mov ah,3eh;функция закрытия
mov bx,handle;дескриптор
int 21h
ret
ReadFile endp
;Обработка согласно варианту
Variant4 proc near
mov cx,buflen
mov di,offset buff+2
mov ax,0
calcstr:
cmp byte ptr[di],' ';Пропустить если пробел
je contlp
inc al;увеличить счетчик символов
contlp:
inc di;следующий символ
loop calcstr;продолжить цикл по CX(CX=CX-1)
mov byte ptr[bytesinstr],' ';Подготовить буфер для
mov byte ptr[bytesinstr+1],' ';отображения длины
mov byte ptr[bytesinstr+2],' ';строки на экране
mov bx,offset bytesinstr+2
call numstrin;перевести число в строку
mov ah,9
lea dx,strout2
int 21h
mov ah,9
lea dx,bytesinstr;вывести количество символов на экран
int 21h
mov ah,9
lea dx,crlf
int 21h
ret
Variant4 endp
; Число в строку:
; ---------------------------
; Вход: AX - Число, BX - строка приёмник
numstrin proc near
mov dl,10; Основание системы счисления
contdiv:
;Число в строку
div dl; разделить AX на DL
;остаток в регистре AH, а частное - в AL
mov byte ptr [bx],ah
add byte ptr [bx],30h
dec bx; сместиться на символ влево
cbw; убрать остаток
cmp al,0; пока частное больше нуля
ja contdiv
ret
numstrin endp
cseg ends
end start
- Вывод:
Я разработал программу для обработки файлов. В программе предусмотрены следующие операции:
Создание файла и занесение в него информации, которую пользователь вводит с клавиатуры, также обработка файла с индивидуальным заданием и запись результатов обработки в новый файл и чтение файлов и вывод информации из файлов на экран монитора. Программа работает.