Днепропетровск

Днепропетровский национальный университет железнодорожного транспорта имени академика

В. Лазаряна

 

 

Кафедра КИТ

 

Отчет

С лабораторной работы № 1

По теме: " Работа с файлами с помощью дескрипторов "

 

 

Выполнил

Студент

926 группы

Попов Д.Ю.

Проверила

Разумов С.Ю.

 

 

Днепропетровск

  1. Мета роботи:

Разработать программу для обработки файлов. В программе следует предусмотреть следующие операции:

- Создание файла занесения в него информации, которую пользователь вводит с клавиатуры;

- Обработка файла с индивидуальным заданием и запись результатов обработки в новый файл;

- Чтение файлов и вывод информации из файлов на экран монитора;

Подсчитать количество символов в каждой строке файла.

  1. Индивидуальное задание:

Подсчитать количество символов в каждой строке файла.

  1. Теория :

Работа с дескрипторами файлов

Дескриптор файла - это целое число без знака, с помощью которого процесс обращается к открытому файлу. В каждом процессе может быть выделено до двух тысяч дескрипторов. Они создаются при выполнении функций 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

 

 

  1. Вывод:

Я разработал программу для обработки файлов. В программе предусмотрены следующие операции:

Создание файла и занесение в него информации, которую пользователь вводит с клавиатуры, также обработка файла с индивидуальным заданием и запись результатов обработки в новый файл и чтение файлов и вывод информации из файлов на экран монитора. Программа работает.