TMember = record
name : string[50];
eMail : string[30];
Posts : LongInt;
end;var
Members: array[1..50] of TMember;Перед тем, как мы сможем записать информацию на диск, нам необходимо объявить переменную типа file. Следующая строка объявляет переменную файла F: var
F: file of TMember;Обратите внимание:
Чтобы создать файл typed в Delphi, мы используем следующий синтакс:var
SomeTypedFile: file of SomeType;Базовый тип (SomeType) для файла может быть скалярным (наподобие Double), массивом или записью. Он не может быть длинной строкой, динамическим массивом, классом, объектом или указателем. Чтобы начать работать с файлом из Delphi нам надо связать файл на диске с переменной файла в нашей программе. Для этого используем процедуру AssignFile. AssignFile(F, 'Members.dat');Как только связь с внешним файлом установлена, переменную F необходимо 'открыть' для подготовки её к чтению или записи. Для открытия существующего файла мы используем процедуру Reset либо Rewrite для создания нового файла. После того, как программа закончит обработку файла, его необходимо закрыть при помощи процедуры CloseFile. Сразу после закрытия файла, связанный с ним внешний файл будет обновлён. Затем переменную файла можно связать с другим внешним файлом. Вообще, мы должны всегда производить обработку исключительных ситуаций, так как при работе с файлами может происходить довольно много ошибок. Например, если мы вызовем CloseFile для файла, который уже закрыт, то Delphi выдаст ошибку I/O. С другой стороны, если мы попробуем закрыть файл, до вызова AssignFile, то результаты могут быть непредсказуемыми. Запись Предположим, что у нас есть массив, заполненный именами, e-мейлами и т.д., и мы хотим сохранить эту информацию на диск. Делается это следующим образом: var
F: file of TMember;
begin
AssignFile(F,'members.dat');
Rewrite(F);
try
for i:= 1 to 50 do
write (F, Members[i]);
finally
CloseFile(F);
end;
end;Чтение Для получения всей информации из файла 'members.dat' используется следующий код: var
Member: TMember
F: file of TMember;
begin
AssignFile(F,'members.dat');
Reset(F);
try
while not Eof(F) do
begin
read (F, Member);
{ Что-нибудь делаем с данными }
end;
finally
CloseFile(F);
end;
end;Обратите внимание:
Eof это функция проверки конца файла (EndOfFile). Мы используем эту функцию, чтобы не выйти за пределы файла (за пределы последней, сохранённой записи).Поиск и позиционирование Обычно, доступ к файлам осуществляется последовательно. При чтении из файла (используя стандартную процедуру Read) или при записи (используя стандартную процедуру Write), текущая позиция в файле перемещается на следующий по порядку компонент (следующая запись). К файлам typed так же можно обращаться через стандартную процедуру Seek, которая перемещает текущую позицию в файле на указанный компонент. Для определения текущей позиции в файле и размера файла можно использовать функции FilePos и FileSize. {устанавливаем на начало - на первую запись}
Seek(F, 0);{устанавливаем на 5-ю запись}
Seek(F, 5);{Переходим в конец - "после" последней записи}
Seek(F, FileSize(F));Изменение и обновление Мы разобрались как записывать и считывать из файла массив Members. А что, если нам нужно найти десятую запись и изменить в ней e-mail? Давайте посмотрим на процедуру, которая делает это: procedure ChangeEMail(const RecN: integer; const NewEMail: string);
var
DummyMember: TMember;
begin
{связывание, открытие, блок обработки исключений}
Seek(F, RecN);
read(F, DummyMember);
DummyMember.Email := NewEMail;
{чтение перемещается на следующую запись, для этого необходимо
вернуться на первоначальную запись, а затем записать}
Seek(F, RecN);
write(F, DummyMember);
{закрываем файл}
end;Всё готово Итак, теперь мы имеем всё, что нам нужно для реализации нашей задачи. Мы можем записать информацию на диск, считать её, и даже изменить некоторые данные (например, e-mail) в "середине" файла. Самое главное, что этот файл не в ASCII формате ! Общий вид модуля выглядит примерно так [здесь для наглядности данные выводятся в StringGrid'e]: unit Unit1;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls, Grids;type
TMember = record
name : string[50];
eMail : string[30];
Posts : LongInt;
end;type
TForm1 = class(TForm)
SaveBtn: TButton;
EnterDataToArrayBtn: TButton;
OpenBtn: TButton;
StringGrid1: TStringGrid;
ChangeEmailBtn: TButton;
procedure SaveBtnClick(Sender: TObject);
procedure EnterDataToArrayBtnClick(Sender: TObject);
procedure OpenBtnClick(Sender: TObject);
procedure ChangeEmailBtnClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;
Members : array[1..50] of TMember;implementation
{$R *.DFM}procedure TForm1.SaveBtnClick(Sender: TObject);
var
F : file of TMember;
i: integer;
begin
AssignFile(F,'members.dat');
Rewrite(F);
try
for i:= 1 to 50 do
write (F, Members[i]);
finally
CloseFile(F);
end;
end;procedure TForm1.EnterDataToArrayBtnClick(Sender: TObject);
begin
Members[1].name:='___Nikolay';
Members[1].eMail:='DelphiWorld@mail.ru';
Members[1].Posts:=10;
Members[2].name:='Sveta';
Members[2].eMail:='sveta29@mail.ru';
Members[2].Posts:=28;
Members[3].name:='Elena';
Members[3].eMail:='malisheva_e@rambler.ru';
Members[3].Posts:=5;
end;procedure TForm1.OpenBtnClick(Sender: TObject);
var
ReadMembers: array[1..50] of TMember;
F: file of TMember;
i: integer;
begin
AssignFile(F,'members.dat');
Reset(F);
try
i:=0;
while not Eof(F) do
begin
read (F, ReadMembers[i]);
////////////////////////
StringGrid1.Cells[0,i]:=ReadMembers[i].name;
StringGrid1.Cells[1,i]:=ReadMembers[i].eMail;
StringGrid1.Cells[2,i]:=IntToStr(ReadMembers[i].Posts);
////////////////////////
i:=i+1;
end;
finally
CloseFile(F);
end;
end;procedure ChangeEMail (const RecN : integer; const NewEMail : string);
var
DummyMember: TMember;
F: file of TMember;
begin
AssignFile(F,ExtractFilePath(Application.ExeName)+'members.dat');
Reset(F);
Seek(F, RecN);
read(F, DummyMember);
DummyMember.Email := NewEMail;
{чтение перемещается на следующую запись, для этого необходимо
вернуться на первоначальную запись, а затем записать}
Seek(F, RecN);
write(F, DummyMember);
CloseFile(F);
end;
procedure TForm1.ChangeEmailBtnClick(Sender: TObject);
begin
ChangeEmail(2, 'bestprogramming@mail.ru');
end;end.