4617
Разработка программ, включающих данные файлового типа
Практическая работа
Информатика, кибернетика и программирование
Цель работы: приобретение практических навыков в разработке программ, включающих данные файлового типа Содержание работы: Программирование работы с файлами последовательного доступа. Программирование работы с файлами произвольного...
Русский
2012-11-23
298 KB
15 чел.
Цель работы:
Содержание работы:
Требования к отчету:
Отчет по работе должен содержать:
Файл представляет собой структурированный тип данных, состоящий из последовательности компонентов определенного типа.
Доступ к компонентам файла осуществляется через указатель файла. При чтении или записи этот указатель автоматически перемещается к следующему компоненту и делает его доступным для обработки.
В Delphi предусмотрено два способа доступа к компонентам файла: последовательный и произвольный (прямой).
При последовательном способе доступа поиск начинается с начала файла и проверяется по очереди каждый компонент, пока не будет найден нужный.
Произвольный способ доступа позволяет обращаться к компоненту по его порядковому номеру в файле.
Допускается значительная гибкость при работе с файлами. Например, компоненты последовательно организованного файла могут обрабатываться произвольно, а компоненты произвольного файла последовательно.
Файлы последовательного доступа используются для решения задач, требующих поочередной обработки компонентов файла при отсутствии жестких ограничений на время решения. Работа с последовательными файлами предполагает:
Для создания последовательного файла необходимо выполнить следующие шаги:
Чтобы обработать хранящиеся в файле данные, необходимо получить доступ к компонентам файла. Для этого надо:
Возможны три вида корректировки последовательного файла:
Все три вида одинаково применимы и к последовательным, и к произвольным файлам. Здесь рассмотрим технологию расширения файлов. При расширении новые компоненты записываются сразу за последним компонентом корректируемого файла.
Расширение файла предполагает выполнение следующих шагов:
Для установки указателя за последним компонентом можно использовать процедуру:
Seek(FV,FileSize(FV));
где FV имя файловой переменной; FileSize(FV) длина файла
1. Организовать последовательный файл с именем BIBL.DAT на диске D:\LZ-05\Zadan_1.
Структура записи следующая:
Значения полей вводятся с клавиатуры.
Признак окончания ввода ввод значения 9999 в поле номера.
Блок организации файла оформить процедурой Org.
2. Вывести на экран содержание всех записей созданного файла. Блок вывода оформить процедурой Obr.
3. Расширить файл BIBL.TXТ двумя новыми компонентами. Блок корректировки файла оформить процедурой Korr.
4. Объединить все процедуры в одной программе и проверить ее работу во всех режимах.
Type
Books = record // Запись типа Books
Nomer: integer; //Номер книги
Avtor: string[20]; //Автор
Nazv: string[40]; //Название книги
Izdat: string[15]; //Издательство
Str: integer; //Количество страниц
end;
Var
BooksFile: file of Books; //Файловая переменная
RecBooks: Books; //Переменная для записи
Процедура организации последовательного файла должна иметь следующий вид:
//Процедура организации последовательного файла
//Выход из процедуры - ответ 9999 для поля Nomer
Procedure Org;
Begin
//Связывание файловой переменной с физическим файлом
AssignFile(BooksFile,'D:\LZ-05\Zadan1\bibl.dat');
Rewrite(BooksFile); //Создание на диске нового файла для записи
while True do
begin
Writeln('Vvedite nomer knigi');
Readln(RecBooks.Nomer);
if RecBooks.Nomer = 9999 then {Если номер книги равен 9999, то выход из процедуры}
begin
CloseFile(BooksFile); //Закрытие файла
Exit //Выход из процедуры
end;
//Ввод исходных данных
Writeln('Vvedite familiu avtora');
Readln(RecBooks.Avtor);
Writeln('Vvedite nazvanie knigi');
Readln(RecBooks.Nazv);
Writeln('Vvedite nazvanie izdatelstva');
Readln(RecBooks.Izdat);
Writeln('Vvedite kolichestvo stranic');
Readln(RecBooks.Str);
Write(BooksFile, RecBooks) //Ввод очередной записи в файл
end
end;
Процедура организации последовательного файла должна иметь следующий вид:
//Процедура доступа к записям последовательного файла
Procedure Obr;
begin
AssignFile(BooksFile,'D:\LZ-05\Zadan1\bibl.dat');
Reset(BooksFile); //Установка указателя в начало файла
while not EOF(BooksFile) do {Пока не достигнут конец файла, читать записи и выводить их на экран}
begin
Read(BooksFile, RecBooks);
Writeln(RecBooks.Nomer:5,RecBooks.Avtor:10,RecBooks.Nazv:40,
RecBooks.Izdat:15,RecBooks.Str:5)
end;
CloseFile(BooksFile)
end;
Процедура корректировки последовательного файла должна иметь следующий вид:
//Процедура корректировки последовательного файла
Procedure Korr;
begin
AssignFile(BooksFile,'D:\LZ-05\Zadan1\bibl.dat');
Reset(BooksFile); //Открытие существующего файла
Seek(BooksFile,FileSize(BooksFile)); {Установка указателя за последним компонентом существующего файла}
while True do //Ввод новых записей
begin
Writeln('Vvedite nomer knigi');
Readln(RecBooks.Nomer);
if RecBooks.Nomer = 9999 then {Если номер книги равен 9999, то выход из процедуры}
begin
CloseFile(BooksFile); //Закрытие файла
Exit //Выход из процедуры
end;
Writeln('Vvedite familiu avtora');
Readln(RecBooks.Avtor);
Writeln('Vvedite nazvanie knigi');
Readln(RecBooks.Nazv);
Writeln('Vvedite nazvanie izdatelstva');
Readln(RecBooks.Izdat);
Writeln('Vvedite kolichestvo stranic');
Readln(RecBooks.Str);
Write(BooksFile, RecBooks) //Ввод очередной записи в файл
end
end;
Операторная часть программы должна выглядеть примерно так:
Begin //Основной блок
while True do
begin
Writeln('Ukajte rejm:');
Writeln(' 1: sozdanie file');
Writeln(' 2: obrabotka file');
Writeln(' 3: rasshirenie file');
Writeln(' 4: vixod iz program');
Readln(Rej);
case Rej of
1: Org; //Вызов процедуры организации файла
2: Obr; //Вызов процедуры доступа к записям файла
3: Korr; //Вызов процедуры корректировки файла
4: Halt //Вызов процедуры прекращения работы программы
else Writeln('Error! Povtorite nomer rejma')
end;
end;
Readln
End.
program Posldost;
{$APPTYPE CONSOLE}
uses
SysUtils;
Type
Books = record // Запись типа Books
Nomer: integer; //Номер книги
Avtor: string[20]; //Автор
Nazv: string[40]; //Название книги
Izdat: string[15]; //Издательство
Str: integer; //Количество страниц
end;
Var
BooksFile: file of Books; //Файловая переменная
RecBooks: Books; //Переменная для записи
Rej: integer; //Номер режима работы
//Процедура организации последовательного файла
//Выход из процедуры - ответ 9999 для поля Nomer
Procedure Org;
Begin
//Связывание файловой переменной с физическим файлом
AssignFile(BooksFile,'D:\LZ-05\Zadan1\bibl.dat');
Rewrite(BooksFile); //Создание на диске нового файла для записи
while True do
begin
Writeln('Vvedite nomer knigi');
Readln(RecBooks.Nomer);
if RecBooks.Nomer = 9999 then {Если номер книги равен 9999, то выход из процедуры}
begin
CloseFile(BooksFile); //Закрытие файла
Exit //Выход из процедуры
end;
//Ввод исходных данных
Writeln('Vvedite familiu avtora');
Readln(RecBooks.Avtor);
Writeln('Vvedite nazvanie knigi');
Readln(RecBooks.Nazv);
Writeln('Vvedite nazvanie izdatelstva');
Readln(RecBooks.Izdat);
Writeln('Vvedite kolichestvo stranic');
Readln(RecBooks.Str);
Write(BooksFile, RecBooks) //Ввод очередной записи в файл
end
end;
//Процедура доступа к записям последовательного файла
Procedure Obr;
begin
AssignFile(BooksFile,'D:\LZ-05\Zadan1\bibl.dat');
Reset(BooksFile); //Установка указателя в начало файла
while not EOF(BooksFile) do {Пока не достигнут конец файла, читать записи и выводить их на экран}
begin
Read(BooksFile, RecBooks);
Writeln(RecBooks.Nomer:5,RecBooks.Avtor:10,RecBooks.Nazv:40,
RecBooks.Izdat:15,RecBooks.Str:5)
end;
CloseFile(BooksFile)
end;
//Процедура корректировки последовательного файла
Procedure Korr;
begin
AssignFile(BooksFile,'D:\LZ-05\Zadan1\bibl.dat');
Reset(BooksFile); //Открытие существующего файла
Seek(BooksFile,FileSize(BooksFile)); {Установка указателя за последним компонентом существующего файла}
while True do //Ввод новых записей
begin
Writeln('Vvedite nomer knigi');
Readln(RecBooks.Nomer);
if RecBooks.Nomer = 9999 then {Если номер книги равен 9999, то выход из процедуры}
begin
CloseFile(BooksFile); //Закрытие файла
Exit //Выход из процедуры
end;
Writeln('Vvedite familiu avtora');
Readln(RecBooks.Avtor);
Writeln('Vvedite nazvanie knigi');
Readln(RecBooks.Nazv);
Writeln('Vvedite nazvanie izdatelstva');
Readln(RecBooks.Izdat);
Writeln('Vvedite kolichestvo stranic');
Readln(RecBooks.Str);
Write(BooksFile, RecBooks) //Ввод очередной записи в файл
end
end;
Begin //Основной блок
while True do
begin
Writeln('Ukajte rejm:');
Writeln(' 1: sozdanie file');
Writeln(' 2: obrabotka file');
Writeln(' 3: rasshirenie file');
Writeln(' 4: vixod iz program');
Readln(Rej);
case Rej of
1: Org; //Вызов процедуры организации файла
2: Obr; //Вызов процедуры доступа к записям файла
3: Korr; //Вызов процедуры корректировки файла
4: Halt //Вызов процедуры прекращения работы программы
else Writeln('Error! Povtorite nomer rejma')
end;
end;
Readln
End.
Таблица 1
Nomer |
Avtor |
Nazv |
Izdat |
Str |
1 |
Ivanenko |
Introduction in Turbo Pascal |
Nauka |
234 |
2 |
Flenov |
Programming in the system Delphi 7 |
Radio |
662 |
3 |
Petrovec |
Beginning of programming |
Dialektika |
428 |
Исходные данные для корректировки файла приведены в табл. 2.
Таблица 2
Nomer |
Avtor |
Nazv |
Izdat |
Str |
4 |
Virt |
Algorithms and structures of data |
Statistika |
406 |
5 |
Perminov |
Programming in language of Pascal |
Radio |
120 |
Структура записи следующая:
Значения полей вводятся с клавиатуры.
Признак окончания ввода ввод значения 255 в поле номера команды.
Отлаженный проект программы сохраните в папке \Мои документы\ЛЗ-05\Задание1а под именем Futbl. В эту же папку скопируйте D:\LZ-05\Zadan1\futball.dat.
Файлы произвольного доступа создаются для решения задач, требующих оперативного доступа к хранимой информации или при наличии зависимости значения поля компонента от порядкового номера компонента в файле. Последовательный доступ в этих случаях неэффективен.
Работа с файлом произвольного доступа предполагает его организацию, обработку и корректировку.
Организовать файл произвольного доступа можно двумя способами:
1) создать последовательный файл и обращаться к компонентам по их порядковому номеру, трактуя последовательный файл как произвольный;
2) создать файл фиктивных записей, затем загрузить его по ключу фактическими данными; обращение к компонентам по ключу предполагает использование процедуры Seek.
Первый способ аналогичен созданию последовательного файла, поэтому рассмотрим второй способ.
Форматизация заключается во внесении в файл компонентов, значение полей которых носит фиктивный характер, например, нули или пробелы.
Доступ к компонентам файла произвольного доступа может быть как последовательный, так и произвольный. Последовательный доступ не отличается от описанного в Задании № 1.
Для организации произвольного доступа используется процедура Seek. Произвольный доступ организовывается по ключу, значение которого равно порядковому номеру в файле нужного компонента. Ключ должен иметь целочисленное значение, не превышающее количество компонентов в файле.
Порядок действий при обработке файлов произвольного доступа следующий:
Корректировка файла произвольного доступа заключается в изменении значений полей компонентов в целом или частично или расширении файла.
Для корректировки полей компонентов файла необходимо:
Шестой пункт необходим, так как после считывания записи указатель файла переместится к следующей записи, поэтому, чтобы откорректированную запись сохранить на старом месте, указатель надо переместить на один компонент вверх.
Процедура корректировки полной записи аналогична описанной выше, только новая запись вносится на место уже существующей фактической записи, а не фиктивной. Возможен и другой вид корректировки файла произвольного доступа добавление компонентов.
1. Организовать файл произвольного доступа из N записей с именем BIBL2.DAT на диске D:\LZ-05\Zadan_2.
Формат записи аналогичен формату записи в Задании № 1.
Значения полей вводятся с клавиатуры.
Блок форматизации файла оформить процедурой Form.
Внести в файл фактические записи 3, 6, 7, 8.
Блок загрузки записей в файл оформить процедурой Zagr.
2. Вывести на экран содержание выбранных записей (6 и 7) созданного файла. Блок вывода оформить процедурой Obr.
3. Осуществить корректировку отдельных полей записи. Могут изменяться реквизиты всех полей, кроме номера книги. Блок корректировки файла оформить процедурой Korr.
4. Объединить все процедуры в одной программе и проверить ее работу во всех режимах.
Type
Books = record // Запись типа Books
Nomer: integer; //Номер книги
Avtor: string[20]; //Автор
Nazv: string[40]; //Название книги
Izdat: string[15]; //Издательство
Str: integer; //Количество страниц
end;
Var
BooksFile: file of Books; //Файловая переменная
RecBooks: Books; //Переменная для записи
N: integer; //Общее количество записей в файле
I,K,K1: integer; //Промежуточные переменные
Rej: integer; //Номер режима работы
FilName: string; //Строка для полного имени файла
Процедура форматизации файла произвольного доступа должна иметь следующий вид:
//Процедура форматизации файла произвольного доступа
Procedure Form;
begin
Writeln('Vvedite polnoe imia sozdavaemogo fila:');
Readln(FilName); //С клавиатуры вводится полное имя файла
AssignFile(BooksFile,FilName);
Rewrite(BooksFile); //Создание нового файла
Writeln('Vvedite kolichestvo zapisey v file:');
Readln(N); //С клавиатуры вводится значение N
for I:=1 to N do //Заполнение записей фиктивными значениями
begin
RecBooks.Nomer:=0;
RecBooks.Avtor:=''; //Пустые строки
RecBooks.Nazv:='';
RecBooks.Izdat:='';
RecBooks.Str:=0;
write(BooksFile,RecBooks) //Запись в файл
end;
Writeln('Formatizacia ',N,' zapisey vipolnena');
CloseFile(BooksFile) //Закрытие файла
end;
После форматизации файла можно приступить к его загрузке по ключу компонентами с фактической информацией, которые будут по мере записи в файл заменять фиктивную информацию.
Процедура загрузки файла произвольного доступа записями должна иметь следующий вид:
//Процедура загрузки файла фактическими записями
Procedure Zagr;
begin
Writeln('Vvedite imia zagrujaemogo po kluchu fila:');
Readln(FilName);
AssignFile(BooksFile,FilName);
Reset(BooksFile); //Указатель устанавливается в начало файла
Writeln('Skolko zapisey budete vvodit?');
Readln(K); //С клавиатуры вводится количество записей
for I:=1 to K do
begin
Writeln('Vvedite nomer knigi, zapis kotoroy nado zagruzit');
Readln(RecBooks.Nomer);
K1:=RecBooks.Nomer;
Writeln('Vvedite familiu avtora');
Readln(RecBooks.Avtor);
Writeln('Vvedite nazvanie knigi');
Readln(RecBooks.Nazv);
Writeln('Vvedite nazvanie izdatelstva');
Readln(RecBooks.Izdat);
Writeln('Vvedite kolichestvo stranic');
Readln(RecBooks.Str);
Seek(BooksFile,K1-1); //Указатель устанавливается
//на нужный компонент файла
Write(BooksFile,RecBooks) //Ввод очередной записи в файл
end;
Close(BooksFile) //Закрытие файла
end;
Когда в файл загружены фактические записи, можно приступать к использованию этой информации.
Процедура доступа к фактическим записям файла произвольного доступа должна иметь следующий вид:
//Процедура доступа к фактическим записям файла
Procedure Obr;
begin
Writeln('Vvedite imia fila:');
Readln(FilName);
AssignFile(BooksFile,FilName);
Reset(BooksFile); //Указатель устанавливается в начало файла
while True do
begin
Writeln('Vvedite nomer vivodimoy zapisi:');
Readln(K1);
if K1=9999 then {Если номер книги равен 9999, то выход из процедуры}
begin
CloseFile(BooksFile);
Exit
end;
Seek(BooksFile,K1-1); //Указатель устанавливается
//на нужную запись
Read(BooksFile,RecBooks); //Чтение записи
//Вывод записи на экран
Writeln(RecBooks.Nomer:5,RecBooks.Avtor:10,RecBooks.Nazv:40,
RecBooks.Izdat:15,RecBooks.Str:5)
end
end;
Процедура корректировки файла произвольного доступа должна иметь следующий вид:
//Процедура корректировки файла произвольного доступа
Procedure Korr;
Var
NewAvtor: string[20]; //Новый автор
NewNazv: string[40]; //Новое название книги
NewIzdat: string[15]; //Новое издательство
NewStr: integer; //Новое количество страниц
begin
Writeln('Vvedite imia fila:');
Readln(FilName);
AssignFile(BooksFile,FilName);
Reset(BooksFile); //Указатель устанавливается в начало файла
Writeln('Skolko zapisey budete korrektirovat?');
Readln(K);
for I:=1 to K do
begin
Writeln('Vvedite nomer korrektiruemoy zapisi:');
Readln(K1);
Writeln('Vvedite familiu novogo avtora');
Readln(NewAvtor);
Writeln('Vvedite novoe nazvanie knigi');
Readln(NewNazv);
Writeln('Vvedite novoe nazvanie izdatelstva');
Readln(NewIzdat);
Writeln('Vvedite novoe kolichestvo stranic');
Readln(NewStr);
//Установка указателя на корректируемую запись
Seek(BooksFile,K1-1);
Read(BooksFile,RecBooks); //Чтение корректируемой записи
RecBooks.Avtor:=NewAvtor;
RecBooks.Nazv:=NewNazv;
RecBooks.Izdat:=NewIzdat;
RecBooks.Str:= NewStr;
//Вновь установка указателя на корректируемую запись
Seek(BooksFile,K1-1);
//Запись в файл новых значений полей
Write(BooksFile,RecBooks)
end;
Close(BooksFile) //Закрытие файла
end;
Операторная часть программы должна выглядеть примерно так:
Begin //Основной блок
while True do
begin
Writeln('Ukajte rejm:');
Writeln(' 1: formatizacia fila');
Writeln(' 2: zagruzka fila po kluchu');
Writeln(' 3: obrabotka fila po kluchu');
Writeln(' 4: korrektirovka fila');
Writeln(' 5: vixod iz program');
Readln(Rej); //Ввод режима с клавиатуры
case Rej of
1: Form; //Вызов процедуры организации файла
2: Zagr; //Вызов процедуры доступа к записям файла
3: Obr; //Вызов процедуры корректировки файла
4: Korr; //Вызов процедуры корректировки файла
5: Halt //Вызов процедуры прекращения работы программы
else Writeln('Error! Povtorite nomer rejma')
end;
end;
Readln
End.
Program Proizdos;
{$APPTYPE CONSOLE}
uses
SysUtils;
Type
Books = record // Запись типа Books
Nomer: integer; //Номер книги
Avtor: string[20]; //Автор
Nazv: string[40]; //Название книги
Izdat: string[15]; //Издательство
Str: integer; //Количество страниц
end;
Var
BooksFile: file of Books; //Файловая переменная
RecBooks: Books; //Переменная для записи
N: integer; //Общее количество записей в файле
I,K,K1: integer; //Промежуточные переменные
Rej: integer; //Номер режима работы
FilName: string; //Строка для полного имени файла
//Процедура форматизации файла произвольного доступа
Procedure Form;
begin
Writeln('Vvedite polnoe imia sozdavaemogo fila:');
Readln(FilName); //С клавиатуры вводится полное имя файла
AssignFile(BooksFile,FilName);
Rewrite(BooksFile); //Создание нового файла
Writeln('Vvedite kolichestvo zapisey v file:');
Readln(N); //С клавиатуры вводится значение N
for I:=1 to N do //Заполнение записей фиктивными значениями
begin
RecBooks.Nomer:=0;
RecBooks.Avtor:=''; //Пустые строки
RecBooks.Nazv:='';
RecBooks.Izdat:='';
RecBooks.Str:=0;
write(BooksFile,RecBooks) //Запись в файл
end;
Writeln('Formatizacia ',N,' zapisey vipolnena');
CloseFile(BooksFile) //Закрытие файла
end;
//Процедура загрузки файла фактическими записями
Procedure Zagr;
begin
Writeln('Vvedite imia zagrujaemogo po kluchu fila:');
Readln(FilName);
AssignFile(BooksFile,FilName);
Reset(BooksFile); //Указатель устанавливается в начало файла
Writeln('Skolko zapisey budete vvodit?');
Readln(K); //С клавиатуры вводится количество записей
for I:=1 to K do
begin
Writeln('Vvedite nomer knigi, zapis kotoroy nado zagruzit');
Readln(RecBooks.Nomer);
K1:=RecBooks.Nomer;
Writeln('Vvedite familiu avtora');
Readln(RecBooks.Avtor);
Writeln('Vvedite nazvanie knigi');
Readln(RecBooks.Nazv);
Writeln('Vvedite nazvanie izdatelstva');
Readln(RecBooks.Izdat);
Writeln('Vvedite kolichestvo stranic');
Readln(RecBooks.Str);
Seek(BooksFile,K1-1); //Указатель устанавливается
//на нужный компонент файла
Write(BooksFile,RecBooks) //Ввод очередной записи в файл
end;
Close(BooksFile) //Закрытие файла
end;
//Процедура доступа к фактическим записям файла
Procedure Obr;
begin
Writeln('Vvedite imia fila:');
Readln(FilName);
AssignFile(BooksFile,FilName);
Reset(BooksFile); //Указатель устанавливается в начало файла
while True do
begin
Writeln('Vvedite nomer vivodimoy zapisi:');
Readln(K1);
if K1=9999 then {Если номер книги равен 9999, то выход из процедуры}
begin
CloseFile(BooksFile);
Exit
end;
Seek(BooksFile,K1-1); //Указатель устанавливается
//на нужную запись
Read(BooksFile,RecBooks); //Чтение записи
//Вывод записи на экран
Writeln(RecBooks.Nomer:5,RecBooks.Avtor:10,RecBooks.Nazv:40,
RecBooks.Izdat:15,RecBooks.Str:5)
end
end;
//Процедура корректировки файла произвольного доступа
Procedure Korr;
Var
NewAvtor: string[20]; //Новый автор
NewNazv: string[40]; //Новое название книги
NewIzdat: string[15]; //Новое издательство
NewStr: integer; //Новое количество страниц
begin
Writeln('Vvedite imia fila:');
Readln(FilName);
AssignFile(BooksFile,FilName);
Reset(BooksFile); //Указатель устанавливается в начало файла
Writeln('Skolko zapisey budete korrektirovat?');
Readln(K);
for I:=1 to K do
begin
Writeln('Vvedite nomer korrektiruemoy zapisi:');
Readln(K1);
Writeln('Vvedite familiu novogo avtora');
Readln(NewAvtor);
Writeln('Vvedite novoe nazvanie knigi');
Readln(NewNazv);
Writeln('Vvedite novoe nazvanie izdatelstva');
Readln(NewIzdat);
Writeln('Vvedite novoe kolichestvo stranic');
Readln(NewStr);
//Установка указателя на корректируемую запись
Seek(BooksFile,K1-1);
Read(BooksFile,RecBooks); //Чтение корректируемой записи
RecBooks.Avtor:=NewAvtor;
RecBooks.Nazv:=NewNazv;
RecBooks.Izdat:=NewIzdat;
RecBooks.Str:= NewStr;
//Вновь установка указателя на корректируемую запись
Seek(BooksFile,K1-1);
//Запись в файл новых значений полей
Write(BooksFile,RecBooks)
end;
Close(BooksFile) //Закрытие файла
end;
Begin //Основной блок
while True do
begin
Writeln('Ukajte rejm:');
Writeln(' 1: formatizacia fila');
Writeln(' 2: zagruzka fila po kluchu');
Writeln(' 3: obrabotka fila po kluchu');
Writeln(' 4: korrektirovka fila');
Writeln(' 5: vixod iz program');
Readln(Rej); //Ввод режима с клавиатуры
case Rej of
1: Form; //Вызов процедуры организации файла
2: Zagr; //Вызов процедуры доступа к записям файла
3: Obr; //Вызов процедуры корректировки файла
4: Korr; //Вызов процедуры корректировки файла
5: Halt //Вызов процедуры прекращения работы программы
else Writeln('Error! Povtorite nomer rejma')
end;
end;
Readln
End.
Количество записей в файле 10.
Исходные данные для создания файла приведены в табл. 2.
Таблица 2
Nomer |
Avtor |
Nazv |
Izdat |
Str |
3 |
Ivanenko |
Introduction in Turbo Pascal |
Nauka |
234 |
6 |
Flenov |
Programming in the system Delphi 7 |
Radio |
662 |
7 |
Petrovec |
Beginning of programming |
Dialektika |
428 |
8 |
Virt |
Algorithms and structures of data |
Statistika |
406 |
Исходные данные для корректировки файла приведены в табл. 3.
Таблица 3
Nomer |
Avtor |
Nazv |
Izdat |
Str |
6 |
Krisevich |
Programming: Delphi 7 |
Nauka |
218 |
8 |
Perminov |
Programming in language of Pascal |
Radio |
120 |
Структура записи следующая:
Значения полей вводятся с клавиатуры.
Количество записей 10.
Признак окончания ввода ввод значения 255 в поле номера команды.
Отлаженный проект программы сохраните в папке \Мои документы\ЛЗ-05\Задание1а под именем Futbl2. В эту же папку скопируйте D:\LZ-05\Zadan1\futball2.dat.
Файл, компонентами которого являются данные символьного типа, называется символьным (или текстовым).
Описание текстового файла в общем виде выглядит так:
Имя: TextFile;
Например:
Type
TText = TextFile;
var
Doc1, Doc2, Kniga: TText;
либо
Var
Doc1, Doc2, Kniga: TextFile;
В текстовых файлах помимо признака конца файла EOF используется дополнительный признак конца строки EOL (End-of-Line), который представляет собой последовательность из двух символов кода ASCII символа с кодом #13 («возврат каретки») и символа с кодом #10 («перевод строки»).
Текстовый файл можно представить как страницу книги, в конце каждой строки которой стоит признак EOL:
код символа |
код символа |
... |
код символа |
код символа |
EOL |
код символа |
код символа |
... |
код символа |
EOL |
|
код символа |
код символа |
... |
EOL |
||
код символа |
код символа |
... |
код символа |
код символа |
EOF |
Работа с текстовым файлом предполагает его организацию, обработку и корректировку.
Для организации текстового файла, прежде всего, надо объявить файловую переменную в качестве текстовой. Затем последовательно выполнить следующие шаги:
Для обработки содержимого текстового файла необходимо получить доступ к его компонентам. Для этого следует выполнить следующее:
Корректировка заключается в расширении текстового файла новыми компонентами. Для этого необходимо:
1. Организовать текстовый файл с именем delpism.txt на диске D:\LZ-05\Zadan_3.
Файл будет содержать строки делового письма.
Каждая строка содержит не более 60 символов.
Если значение вводимой строки равно 'zzz', то следует прекратить запись строк в файл.
Блок создания текстового файла оформить процедурой Sozdt.
2. Вывести на экран все компоненты файла. Блок вывода оформить процедурой Obrt.
3. Расширить созданный файл новыми строками. Если значение вводимой строки равно 'zzz', то прекратить запись строк в файл. Блок корректировки файла оформить процедурой Rasht.
4. Объединить все процедуры в одной программе и проверить ее работу во всех режимах.
Type
Dlina = string[60]; //Максимальная длина строки
Var
Stro : textfile; //Файловая переменная
FilName: string; //Строка для полного имени файла
S : Dlina; //Промежуточная строковая переменная
Rej : byte; //Номер режима работы программы
Процедура создания текстового файла должна иметь следующий вид:
Procedure Sozdt;
begin
Writeln('Vvedite polnoe imia sozdavaemogo textovogo fila:');
Readln(FilName); //С клавиатуры вводится полное имя файла
Assign(Stro,FilName);
Rewrite(Stro); //Открытие создаваемого файла
while True do
begin
Writeln('Vvedite ocherednyu stroku i najmite ENTER');
Readln(S); //Ввод с клавиатуры очередной строки
{Если введенная строка равна zzz, то закрыть файл и выйти из процедуры}
if S = 'zzz' then
begin
CloseFile(Stro);
Exit
end;
Writeln(Stro,S) //Запись очередной строки в файл
end
end;
Процедура чтения текстового файла должна иметь следующий вид:
Procedure Obrt;
begin
Writeln('Vvedite polnoe imia textovogo fila:');
Readln(FilName); //С клавиатуры вводится полное имя файла
Assign(Stro,FilName);
Reset(Stro); //Открытие текстового файла
{Продолжать чтение строк, пока не будет достигнут конец файла}
while not SeekEof (Stro) do
begin
Readln(Stro,S); //Чтение очередной строки из файла
Writeln(S) //Вывод строки на экран
end
end;
Процедура расширения текстового файла должна иметь следующий вид:
Procedure Rasht;
begin
Writeln('Vvedite polnoe imia textovogo fila:');
Readln(FilName); //С клавиатуры вводится полное имя файла
Assign(Stro,FilName);
Append(Stro);
while True do
begin
Writeln('Vvedite ocherednyu stroku i najmite ENTER');
Readln(S); //Ввод с клавиатуры очередной строки
{Если введенная строка равна zzz, то закрыть файл и выйти из процедуры}
if S = 'zzz' then
begin
CloseFile(Stro);
Exit
end;
Writeln(Stro,S) //Запись очередной строки в файл
end
end;
Операторная часть программы должна выглядеть примерно так:
Begin //Основной блок
while True do
begin
Writeln('Ukajte rejm:');
Writeln(' 1: sozdanie textovogo fila');
Writeln(' 2: vivod textovogo fila');
Writeln(' 3: racshirenie textovogo fila');
Writeln(' 4: vixod iz program');
Readln(Rej); //Ввод режима с клавиатуры
case Rej of
1: Sozdt; //Вызов процедуры создания текстового файла
2: Obrt; //Вызов процедуры вывода файла на экран
3: Rasht; //Вызов процедуры расширения файла
4: Halt //Вызов процедуры прекращения работы программы
else Writeln('Error! Povtorite nomer rejma')
end;
end;
Readln
End.
Program TextFiles;
{$APPTYPE CONSOLE}
uses
SysUtils;
Type
Dlina = string[60]; //Максимальная длина строки
Var
Stro : textfile; //Файловая переменная
FilName: string; //Строка для полного имени файла
S : Dlina; //Промежуточная строковая переменная
Rej : byte; //Номер режима работы программы
//Процедура создания текстового файла
Procedure Sozdt;
begin
Writeln('Vvedite polnoe imia sozdavaemogo textovogo fila:');
Readln(FilName); //С клавиатуры вводится полное имя файла
Assign(Stro,FilName);
Rewrite(Stro); //Открытие создаваемого файла
while True do
begin
Writeln('Vvedite ocherednyu stroku i najmite ENTER');
Readln(S); //Ввод с клавиатуры очередной строки
{Если введенная строка равна zzz, то закрыть файл и выйти из процедуры}
if S = 'zzz' then
begin
CloseFile(Stro);
Exit
end;
Writeln(Stro,S) //Запись очередной строки в файл
end
end;
//Процедура вывода текстового файла на экран
Procedure Obrt;
begin
Writeln('Vvedite polnoe imia textovogo fila:');
Readln(FilName); //С клавиатуры вводится полное имя файла
Assign(Stro,FilName);
Reset(Stro); //Открытие текстового файла
{Продолжать чтение строк, пока не будет достигнут конец файла}
while not SeekEof (Stro) do
begin
Readln(Stro,S); //Чтение очередной строки из файла
Writeln(S) //Вывод строки на экран
end
end;
//Процедура расширения текстового файла
Procedure Rasht;
begin
Writeln('Vvedite polnoe imia textovogo fila:');
Readln(FilName); //С клавиатуры вводится полное имя файла
Assign(Stro,FilName);
Append(Stro);
while True do
begin
Writeln('Vvedite ocherednyu stroku i najmite ENTER');
Readln(S); //Ввод с клавиатуры очередной строки
{Если введенная строка равна zzz, то закрыть файл и выйти из процедуры}
if S = 'zzz' then
begin
CloseFile(Stro);
Exit
end;
Writeln(Stro,S) //Запись очередной строки в файл
end
end;
Begin //Основной блок
while True do
begin
Writeln('Ukajte rejm:');
Writeln(' 1: sozdanie textovogo fila');
Writeln(' 2: vivod textovogo fila');
Writeln(' 3: racshirenie textovogo fila');
Writeln(' 4: vixod iz program');
Readln(Rej); //Ввод режима с клавиатуры
case Rej of
1: Sozdt; //Вызов процедуры создания текстового файла
2: Obrt; //Вызов процедуры вывода файла на экран
3: Rasht; //Вызов процедуры расширения файла
4: Halt //Вызов процедуры прекращения работы программы
else Writeln('Error! Povtorite nomer rejma')
end;
end;
Readln
End.
Все файлы, рассмотренные выше, имели строго определенный тип. Однако в ряде случаев пользователь может не знать всех типов файлов, с которыми ему необходимо работать. Обычно такая ситуация возникает при копировании отдельных файлов или объединении нескольких файлов в один результирующий. Для реализации подобных случаев в языке Delphi используются файлы, не имеющие типа (нетипизированные файлы), которые совместимы со всеми типами файлов. Нетипизированные файлы описываются с помощью ключевого слова file:
Var <Файловая_переменная>: file;
Например,
Var
NewFile, OldFile: file; //Бестиповые файлы
Процедуры открытия нетипизированного файла для чтения или записи (Reset и Rewrite) имеют по два параметра. Кроме имени файловой переменной, в их вызовах указывается размер внешнего буфера в байтах. Этот буфер называется блоком. Через него данные копируются из физического файла во внутренний буфер и наоборот. Размер блока может быть в пределах от 1 до 65535 байт. Например, Reset(f,128), Reset(f,1), Rewrite(g,512), Rewrite(g,1).
Нетипизированные файлы обрабатываются с помощью специальных процедур:
BlockRead(FV,Pr,Count,Result)
BlockWrite(FV,Pr,Count,Result);
где FV имя файловой переменной;
Pr переменная любого типа (обычно это массив) задает место в памяти, с которого начинается «внутренний буфер»;
Count количество блоков, которое надо прочитать из файла или записать в файл;
Result количество блоков, которое было передано фактически при выполнении вызова.
Например, пусть действуют такие определения:
Var
f: file; //Задание файловой переменной для бестипового файла
inbuf: array[1..100] of char; //Буфер для ввода
blksz: longint; //Размер блока чтения
nblk: longint; //Число блоков желаемое
nblkreal: longint; //Число блоков действительное
Тогда следующие операторы и вызовы процедур
blksz:=4;
nblk:=25;
Reset(f,blksz);
BlockRead(f,inbuf,nblk,nblkreal);
устанавливают размер блока равным 4 байтам и задают чтение 25 таких блоков из файла. Если размер файла в действительности не меньше 4*25 = 100 байт и ошибок при чтении не было, то значением переменной nblkreal является 25. После чтения массив inbuf заполнен до конца и затем обрабатывается в зависимости от конкретной задачи. Кроме того, при выполнении следующего вызова процедуры BlockRead файл f будет читаться, начиная со 101-го байта.
Возможно, в файле меньше, чем 100 байт или при чтении что-то случилось, и в действительности прочитано меньше, чем указанные 25 блоков. Тогда значение переменной nblkreal будет меньше 25.
Если задать чтение блоков, число которых меньше 25, массив inbuf заполняется не до конца, а если больше заполнится массив inbuf и соответствующее количество переменных, расположенных после массива в памяти программы. Поскольку переменные располагаются в порядке определения, первыми «жертвами» в данном случае станут переменные blksz, nblk, nblkreal. Они имеют тип longint и занимают по 4 байта, поэтому при выполнении BlockRead(f,inbuf,26,nblkreal); будет испорчена только первая из них, при BlockRead(f,inbuf,27,nblkreal); - первые две и т.д.
Если блок, т.е. внешний буфер не заполняется до конца, то количество блоков, прочитанных в действительности, меньше заданного. Во избежание неприятностей нужно обеспечить, чтобы размер файла делился на размер блока. Поскольку размер блока в действительности не влияет на скорость чтения, лучше всего давать ему значение 1. Тогда проблем не будет при любом размере файла.
Если обрабатывается файл записей фиксированного размера, то этот размер можно задавать и для блока. Например, записи типа
Student = record
Sname,Name: string[30];
Ball: real
end;
имеют размер 31+31+6 = 68 байт. Это значение возвращается из вызова SizeOf(Student), поэтому бестиповый файл f, связанный с файлом записей типа Student, можно открыть вызовом Reset(f,SizeOf(Student));
После этого вызов вида
BlockRead(f,Buf,n,nreal);
задает чтение n блоков по 68 байт в память переменной Buf.
Главную роль в скорости чтения бестиповых файлов играет размер внутреннего буфера. Чем он больше, тем меньше обращений к внешнему носителю и быстрее обработка файла. Тем не менее, если размер буфера кратен 512 байт и больше 8 Кбайт, скорость чтения файлов будет практически постоянной.
Процедура блочного вывода BlockWrite также имеет 4 аналогичных параметра. Отличие заключается в том, что данные из внутреннего буфера через блок записываются в конец файла. Предварительно для файла нужно установить размер внешнего буфера с помощью вызова процедуры вида ReWrite(f,m);
1. Организовать пустой целевой текстовый файл с именем file-c.txt на диске D:\LZ-05\Zadan_4. В этот файл будут осуществляться копирование.
2. Скопировать в эту папку D:\LZ-05\Zadan_4 файл Лекция 05 - СТРУКТУРЫ ДАННЫХ.doc из папки Технологии программирования\Модуль 2\ и переименовать его в file-i.doc.
3. Создайте программу копирования файла file-i.doc в файл file-c.txt с использованием бестиповых файлов.
program QuickCopy;
{$APPTYPE CONSOLE}
uses
SysUtils;
const Bufsz=32768; //Размер буфера
var f,g: file; //Файловые переменные исходного и целевого файлов
Buf: array[1..Bufsz] of char; //Буфер
restfile: longint; //Размер остатка файла
portion: longint; //Размер очередной порции
rdin: longint; //Число реально прочитанных байтов
wrou: longint; //Число реально записанных байтов
s_i, s_c: string; //Внешние имена исходного и целевого файлов
begin
Writeln('Vvedite imia fila-istochnika:');
Readln(s_i);
AssignFile(f,s_i);
Writeln('Vvedite imia celevogo fila:');
Readln(s_c);
AssignFile(g,s_c);
Reset(f,1);
Rewrite(g,1);
restfile:=FileSize(f); //Число байт для копирования
while restfile > 0 do
begin
if restfile > Bufsz then portion:=Bufsz
else portion:=restfile;
//Остаток уменьшается на размер скопированной порции
dec(restfile,portion);
Blockread(f,Buf,portion,rdin);
if rdin <> portion then
begin
Writeln('Error chtenia fila');
Halt
end;
Blockwrite(g,Buf,portion,wrou);
if wrou <> portion then
begin
Writeln('Error zapisi fila');
Halt
end;
end;
CloseFile(g);
CloseFile(f);
Readln
end.
Приложение А
Для организации эффективной и удобной работы с файлами в языке Delphi предусмотрен ряд процедур и функций. При их описании используются следующие обозначения:
FV файловая переменная;
Str строковое выражение;
Р переменные p1, р2, ..., рn того же типа, что и компоненты переменной FV;
n целочисленное выражение.
Процедуры
Процедуры осуществляют все необходимые действия по организации файлов и доступу к компонентам файлов.
Функции
Функции выполняют дополнительные действия, облегчающие программисту обслуживание уже существующих файлов.
А также другие работы, которые могут Вас заинтересовать | |||
7231. | Конструкция и материал оптических волокон | 453 KB | |
Конструкция и материал оптических волокон. Оптические волокна можно разделить на следующие типы: кварцевые, кварц-полимерные и полимерные. Кварцевые оптические волокна изготавливаются из высокочистого кварцевого стекла (сердечник и светоотражающая о... | |||
7232. | Расчет напряжений в молитных и бандажированных штампах | 443 KB | |
Теория обработки металлов давлением Расчет напряжений в молитных и бандажированных штампах. Исходные данные: Диаметр поковки: 115 мм Высота поковки: 90 мм Марка стали поковки: Сталь 50 Истинный предел текучести: МПа Размеры монолитного штампа.... | |||
7233. | Организация работы участка по ремонту топливной аппаратуры на АТП в г. Ростове на Дону | 298 KB | |
Введение Перевозки автомобильным транспортом предполагают использование подвижного состава (автомобилей и автопоездов), находящегося в исправном техническом состоянии. Исправное техническое состояние означает полное соответствие подвижного состава н... | |||
7234. | Статистические оценки параметров распределения. Точечные и интервальные оценки параметров распределения | 56 KB | |
Статистические оценки параметров распределения Пусть требуется изучить количественный признак некоторой совокупности. Построив вариационный ряд и изобразив его графически, можно получить первоначальное представление о виде распределения.... | |||
7235. | Статистическая проверка статистических гипотез | 68 KB | |
Лекция 3. Статистическая проверка статистических гипотез. Часто необходимо знать закон распределения генеральной совокупности. Если закон распределения неизвестен, но имеются основания предположить, что он имеет определенный вид, то выдвигают гипоте... | |||
7236. | Элементы теории корреляции | 57 KB | |
Лекция 4. Элементы теории корреляции. Во многих задачах требуется установить и оценить зависимость изучаемой случайной величины Y от случайной величины X. Статистической называют зависимость, при которой изменение одной из величин влечет изменение р... | |||
7237. | Статистическое планирование эксперимента | 41 KB | |
Лекция 5. Статистическое планирование эксперимента Чтобы провести экспериментальные исследования наиболее эффективно необходим научный подход к его планированию. Инициатором применения статистических методов в планировании экспериментов является Рон... | |||
7238. | Интервальное оценивание параметров нормально распределенной случайной величины. Доверительные интервалы для математического ожидания | 450.5 KB | |
ТЕМА: Интервальное оценивание параметров нормально распределенной случайной величины. Доверительные интервалы для математического ожидания. Доверительный интервал для дисперсии. Доверительный интервал для параметров пуассоновского распределения. Дов... | |||
7239. | Точечные оценки математического ожидания. Точечные оценки дисперсии. Точечная оценка вероятности события | 537 KB | |
ТЕМА: Точечные оценки математического ожидания. Точечные оценки дисперсии. Точечная оценка вероятности события. Точечная оценка параметров равномерного распределения. п.1. Точечные оценки математического ожидания. Предположим, что функция распределе... | |||