Дописать в файл в delphi
← →
zorik © ( 2006-01-26 12:13 ) [0]
Есть текстовий файл. В конец файла нужно дописать все строчки StringList. Есть ли варианты, кроме перебора всех строчек списка?
← →Digitman © ( 2006-01-26 12:17 ) [1]
Есть.
Открываешь файл в TFileStream, позиционируешь курсор в конец стрима, читаешь содержимое StringList.Text во врем.буфер, записываешь этот буфер в TFileStream, закрываешь стрим.
Спасибо. Этот вариант будет быстрее, я так понимаю
← →Digitman © ( 2006-01-26 12:20 ) [3]
Единственное, что может еще понадобиться :
1. перед записью буфера убедиться в том что конец файла не содержит символ EOF. Если содержит, сместить стоящий в конце курсор стрима на один символ назад
2. Перед записью буфера записать в стрим CRLF
← →PZ ( 2006-01-26 12:44 ) [4]
Можно предложить такой вариант:
Var
List1 : tStringList; // Список, который надо добавить
List2 : tStringList;
begin
List2 := tStringList.Create;
List2.LoadFromFile("Text.txt");
List2.Add(List1.Text);
List2.SaveToFile("Text.txt");
List2.Free;
end;
Dmitrij_K ( 2006-01-26 12:49 ) [5]
[4] если только файлы маленькие )
← →Gero © ( 2006-01-26 12:52 ) [6]
> если только файлы маленькие )
Да, если не больше 2 Гб.
zorik © ( 2006-01-26 14:42 ) [7]
> [4] если только файлы маленькие )
Файлы "большие". Log расчетов
> Да, если не больше 2 Гб.
Больше 2 Гб не будет.
В клиента Win98 128Mb RAM + расчет забирает память в динамические массивы. Поэтому идея была писать по процедурах. Первая создает файл, остальные ее дописывают. Каждая пишет примерно от 1000 до 3000 строк. Процедур 10-20. Точно не знаю сколько, так как еще не дописал, и возможно надо будет некоторые из промежуточных "Log-инить"
> Digitman © (26.01.06 12:17) [1]
begin
f:=TFileStream.Create(Filename, fmOpenReadWrite);
try
if f.Size > 0 then //файл не пуст ?
begin
f.Position := f.Size - 1; //позиционируем курсор на последнем символе
f.ReadBuffer(CharBuf, 1); //читаем символ в буфер
if CharBuf = EOF then //символ = EOF ?
f.Position := f.Size - 1; //да, вновь позиционируем курсор на нем - отныне конец файла не здесь, а далее
f.WriteBuffer(PChar(CRLF)^, 2); //пишем разделитель строк (в предположении что его нет в конце перезаписываемого ориг.файла)
StringList.SaveToStream(f); //и наконец пишем собственно блок новых строк с разделителями
finally
f.Free;
end;
zorik © ( 2006-01-26 16:06 ) [9]
Спасибо! Все получилось.
Еще 2 маленьких вопросика для образования
2) Когда именно происходить запись в файл. Открыт файл для чтения и для записи. Это происходит при манипуляциях с TFileStream или при его освобождении
function THandleStream.Write(const Buffer; Count: Longint): Longint;
begin
Result := FileWrite(FHandle, Buffer, Count);
if Result = -1 then Result := 0;
end;
function FileWrite(Handle: Integer; const Buffer; Count: LongWord): Integer;
begin
if not WriteFile(THandle(Handle), Buffer, Count, LongWord(Result), nil) then
Result := -1;
Result := __write(Handle, Buffer, Count);
end;
в Digitman © (26.01.06 15:04) [8] нету процедуры Write. После StringList.SaveToStream(f) следует f.Free
← →Zeqfreed © ( 2006-01-26 17:37 ) [12]
zorik © (26.01.06 16:45) [11]
TStringList = class(TStrings)
procedure TStrings.SaveToStream(Stream: TStream);
var
S: string;
begin
S := GetTextStr;
Stream.WriteBuffer(Pointer(S)^, Length(S));
end;
procedure TStream.WriteBuffer(const Buffer; Count: Longint);
begin
if (Count <> 0) and (Write(Buffer, Count) <> Count) then
raise EWriteError.CreateRes(@SWriteError);
end;
Когда речь идет о работе программы с текстовым файлом, подразумеваются процедуры ввода данных из файла в программу или, наоборот, запись этих данных в файл программой. Для текстового файла допустима простая работа с файлом без особых дополнительных механизмов, которые применяются для работы со специализированными файлами, такими как при загрузке данных из Excel или работе программы с базой данных. Разумеется, Delphi располагает возможностями работать с файлами с использованием компонентов. Но в данной статье рассматривается механизм прямой работы с текстовым файлом без использования дополнительных компонентов.
Итак, в общем виде, работа с файлом заключается в следующих этапах:
1. подключение к файлу – связь с внешним файлом, указание режима подключения;
2. выполнение операций записи в файл или чтения из файла;
3. завершение работы с файлом.
Создание нового файла.
Процедура ReWrite(varF) либо создаёт новый файл, либо уничтожает уже имеющийся и на его месте создаёт новый.
Добавление записей в существующий файл.
Добавить новую запись в текстовый файл можно только в его конец.
Процедура Append(varF) открывает текстовый файл для добавления записи в конец текстового файла.
Пример.
procedure TForm1.Button1Click(Sender: Tobject);
var f:textFile;
begin
assignFile(f,’myTextFile.txt’);//так как не указан полный путь доступа к файлу, он запишется в папку с «.exe» файлом программы.
rewrite(f);//создаем (или пересоздаём) файл
//пока ничего не записываем
closeFile(f);//закрываем файл. Если файл не закрыть, к нему нельзя будет обратиться из другого процесса (например, попытка чтения self.ListBox1.Items.LoadFromFile(‘myTextFile.txt’); вызовет ошибку);
end;
procedure TForm1.Button2Click(Sender: Tobject);
var s,s1:string; f:textFile;
begin
assignFile(f,’myTextFile.txt’);
append(f);//открываем файл для добавления записей
s:=’123′;
s1:=’abc’;
writeLn(f,s,s1);//записываем первую строку
s:=’456′;
s1:=’xyz’;
writeLn(f,s,s1);//записываем вторую строку
closeFile(f);//закрываем файл
self.ListBox1.Items.LoadFromFile(‘myTextFile.txt’);//отображаем содержимое файла в компоненте ListBox1
В результате имеем:
procedure TForm1.Button3Click(Sender: Tobject);
var s,s1,s2,s3,s4:string; f:textfile; i,ii:integer; c:char; r:real;
begin
assignfile(f,’3.txt’);
reset(f);//открываем текстовый файл для чтения
readLn(f,s);//читаем первую строку
self.Memo1.Lines.Add(s);//добавляем строку в компонент «Tmemo»
readLn(f,s);//читаем вторую строку
self.Memo1.Lines.Add(s);
В результате будем иметь:
procedure TForm1.Button4Click(Sender: Tobject);
var s,s1:string; f:textFile;
begin
assignFile(f,’myTextFile.txt’);
append(f);//открываем файл для добавления записей
s:=’123′;
s1:=’abc’;
write(f,s,s1);//записываем первую строку
s:=’456′;
s1:=’xyz’;
write(f,s,s1);//записываем вторую строку
closeFile(f);//закрываем файл
self.ListBox1.Items.LoadFromFile(‘myTextFile.txt’);//отображаем содержимое файла в компоненте ListBox1
В результате имеем:
procedure TForm1.Button5Click(Sender: Tobject);
var s,s1:string; f:textFile;
begin
read(f,s);
self.Memo1.Lines.Add(s);
В результате имеем:
Посимвольное прочтение файла.
procedure TForm1.Button6Click(Sender: Tobject);
var s,s1:string; f:textFile; c:char;
begin
repeat
read(f,c);
memo1.Lines.Add(c);
until eoln(f);//читаем посимвольно до тех пор, пока не достигнем конца строки
repeat
read(f,c);
memo1.Lines.Add(c);
until eoln(f);
В результате имеем:
Замечание. Можно сразу прочитать весь файл до конца:
repeat
read(f,c);
memo1.Lines.Add(c);
until eof(f);//завершить, когда будет достигнут конец файла.
Delphi 7. Занятие 1_10.
Видео. Создаём обработчики событий для записи и чтения данных из файла.
Нетипизированные файлы.
Исходная информация переводится в двоичный вид, разбивается на блоки одинакового объёма и записывается на носитель.
Типы файлов.
В Delphi различают три типа файлов:
- текстовые
- типизированные
- нетипизированные
Сохранение данных в типизированный файл.
Процедура Write.
Она аналогична процедуре WriteLn,но не вставляет символы конца строки. Если в предыдущем примере заменить WriteLn на Write, то будем иметь:
Сохранение результатов разработки программы.
Создавая текст программы, в процессе работы над ней и по окончанию её мы сохраняем на диск проект и все модули. Выбрав «Save All … » в меню «File» мы автоматически сохраняем все файлы проекта.
Выбрав «Save», сохраняем текущий модуль. «Save As …» позволяет переименовать модуль и вместо стандартного имени Unit1 задать более осмысленное имя, состоящее из латинских букв, цифр и знака подчёркивания.
«Save Project As …» позволяет задать имя всему проекту, отличное от project1.
«Close» закрывает активную вкладку.
Но всё это касается файлов самого проекта.
А как быть, если надо сохранить данные, полученные в ходе работы программы? Это могут быть числа, текст, массив, запись (о типе данных запись поговорим позднее), отдельный символ (тип данных char).
Это могут быть просто цепочки байт, описывающих, например, изображение. В этом случае говорят, что записываются блоки памяти.
Разберёмся, как это делается.
Открытие существующего файла.
Существующий текстовый файл можно открыть для чтения.
Процедура Reset(varF) открывает файл для чтения (или переоткрывает его). Указатель файла перемещается в начальную позицию.
Запись в текстовый файл.
Рассмотрим, как осуществляется в delphi запись в файл.
Чтобы текст правильно читался из файла, необходимо, чтобы он был разбит на предложения.
Запись такого символа происходит автоматически, если использовать процедуру:
WriteLn( vMyTextFile, s1 [, … , si, … , sn]); , где si — строковая переменная.
Квадратные скобки обозначают, что указанные в них выражения могут присутствовать, а могут и не присутствовать в процедуре. Эти скобки употребляются при описании операторов в общем виде и не должны присутствовать в реальном тексте программы.
Замечание.
Не используйте процедуру Write вместо WriteLn, иначе получите в файле «кашу» или ошибку записи!
Далее мы можем завершить работу с файлом, или переоткрыть его для чтения.
Если, прочитав из файла несколько значений, возникает необходимость дописать строки в конец файла, то его надо переоткрыть процедурой Append(unit1.vFile).
Замечание.
К сожалению, текстовый файл нельзя исправлять напрямую. Нельзя, например, переписать вторую строку.
Для внесения изменений надо прочитать весь файл, отобразить его в каком либо компоненте, например memo, отредактировать, заново пересоздать файл и перезаписать текст из memo в файл.
Завершение работы с файлом закрывает файл. С практической точки зрения это означает, что к файлу больше нельзя обратиться процедурами записи или чтения. С другой стороны, теперь файл доступен для удаления и редактирования средствами файловой системы, например, с помощью «блокнота».
Замечание. Закрытие программы автоматически закрывает все открытые файлы. Управлять файлами (например удалить, переименовать и так далее) можно из программы, используя предназначенные для этого процедуры и функции (об этом разговор будет позже).
Процедура WriteLn.
Procedure WriteLn( varF, Var1,Var2,Var3, … , VarI, … , VarN)
Процедура записывает символьные представления переменных. После переменной VarN будет записан признак конца строки EOLN (End of Line).
Чтобы записать следующую строку, надо вновь применить процедуру WriteLn, и так далее.
Например. s1:=’123′; s2:=’abc’; s3:=’456′; s4:=’xyz’;WriteLn( varF, s1,s2); WriteLn( varF,s3,s4); Будут сфомированы две строки:
Формат записи в файл.
Запись производится посимвольно. Каждый символ занимает 1 байт (или 2 байта в системе Unicode). Например, слово АБВГ займёт 4 байта, а целое число 123456 займёт 6 байт.
Простые и структурированные типы данных.
Под переменные стандартных типов отводится оговоренное количество байт памяти. Под Integer 4 байта, под Double 8 байт, под Char 1 байт и так далее.
Но команды, которые манипулируют данными, хранят адрес только первого байта переменной. Информация о том, сколько надо прочитать байт и как эту цепочку байт интерпретировать, также хранится в команде.
Совокупность длины переменной и способа интерпретации последовательности байт можно назвать типом данных.
Указанные типы называются простыми типами данных.
По мере развития вычислительной техники и возрастания её возможностей стали вводиться более сложные, структурированные типы данных.
Чтобы работать с типом данных «массив» надо хранить информацию о том, что мы имеем дело с последовательностью байт, где начинается эта
последовательность, указать общее количество байт и на какие «порции» надо делить эту последовательность (указать тип данных).
Обычный массив характерен тем, что длина всех элементов массива одинакова.
В отличие от него, динамический массив может иметь разную мощность по разным измерениям. Например, двумерный динамический массив может содержать по первому измерению 5 элементов, а по второму — 10.
Но тип всех элементов всё равно остаётся одинаковым. Например, Integer.
Текстовые файлы.
В тектсовых файлах хранится информация, интерпретируемая как непрерывный последовательный набор текстовых символов.
Операции с файлами
Для чтения из файла, необходимо назначить режим чтения и использовать команду Readln(), которая будет вводить в строковую переменную по одной строке из файла. Затем с этой переменой можно выполнить необходимые действия.
Обычно для загрузки всех строк из файла используется оператор цикла. Для того, чтобы определить, что файл закончился используется функция EOF() (End Of File). Таким образом получается цикл, в котором последовательно в строковую переменную вводятся все строки файла и завершающийся после окончания фала:
Для записи, назначение режим записи в файл и командой Writeln() производится запись по строкам.
Типизированный файл.
В типизированном файле информация хранится как набор последовательностей, имеющих одинаковую длину. Тип каждой последовательности может быть:
- Порядковый
- Вещественный
- Массив
- Запись
- Множество
Процедура ReadLn.
Однократное применение рпоцедуры приводит к считыыванию одной строки.
Например. Файл записан двукратным применением процедуры WriteLn. Применим двукратно процедуру ReadLn(varF,s); где s — строковая переменная.
Первое прочтение даст s=’123abc’, а второе s=’456xyz’.
Замечание 1. Хотя во многих учебниках говорится, что справедлива форма процедуры ReadLn(varF,s,s1,s2, …, sN);, практика показывает, что считывание производится только в переменную s. Остальные переменные принимают значение «пусто».
Замечание 2.Если применить процедуру в виде ReadLn(varF), то будет просто пропущена очередная запись.
Компонент TBitBtn
Продолжим знакомиться с компонентами. На вкладке Additional находится компонент TbitBtn.
Это кнопка с расширенным набором свойств.
Познакомимся с некоторыми из них, которые будут важны в данном занятии.
Если обычная кнопка TButton имеет минимальные возможности по формированию своего внешнего вида, то у TbitBtn таких возможностей гораздо больше.
Для записи в поток подготовим кнопу типа TbitBtn и настроим её так, чтобы она имела в конечном итоге вид:
Как видно из рисунка, на кнопке появилась пиктограмма (красный кружок), Название кнопки выведено в трёх строках. Изменён цвет шрифта.
Для отображения названия кнопки в нескольких строках посмотрим, как хранятся строки в компоненте memo.
В окне текст отображается в виде отдельных строк. А в свойстве Memo1.Text он хранится в виде:
В Object Inspector нельзя добиться вставки этих служебных символов в строку. Они будут воспроизведены как простой текст.
Чтобы служебные символы сыграли свою роль, надо отдельно сформировать строку с их присутствием и записать в свойство Caption.
Удобнее всего это сделать в обработчике создания формы:
procedure TForm1.FormCreate(Sender: TObject);
begin
end;
Цвет символов можно изменить, раскрыв свойство Font, нажав на «+». В выпадающем списке Color можно выбрать нужный цвет символов.
Как видно на рисунке, для кнопки можно организовать подсказку. Для этого надо заполнить свойство Hint (в нашем случае там написано «подсказка») и разрешить её отображать (выставить свойство ShowHint в true).
И наконец, на кнопке отображена небольшая пиктограмма. Она подготавливается заранее в текстовом редакторе и загружается через свойcтво Glyph).
Замечание. Загрузка пиктограммы для отображения на кнопке имеет свои особенности, познакомиться с которыми можно в справочной литературе.
Запись в текстовый файл.
Запись осуществляется операторами WriteLn и Write
Предварительные замечания.
Прежде, чем начать разговор о нетипизиованных файлах, сделаем ещё несколько замечаний по поводу записи в типизированный файл в delphi.
Они будут необходимы нам в дальнейшем при работе с нетипизированными файлами.
Процедура Read.
Если файл записан с помощью процедуры WriteLn, то процедура Read стчитывает только первую запись. Второе применение Read приводитк тому же результату, то есть считываение не идёт дальше первой записи.
Если файл записан с помощью процедуры Write, то Read(varF,s) прочитает весь файл до конца и разместит его содержимое в переменной s.
Например. Если файл сформирован с помощью процедуры Write (как показано выше):
то Read(varF,s) вернёт s=123abc 456xyz.
Запись чисел в текстовый файл.
Целые и вещественные числа записываются обычным образом.
Например, writeLn(varF,i); где i — переменная целого типа. Аналогично записывается вещественное число.
Запись числа можно считать или обычным образом, представив его в виде строки: ReadLn(varF,s), или непосредственно в формате целого числа: ReadLn(varF,i).
Для вещественного числа процедура ReadLn(varF,s)вернёт:
edit4.Text:=floatToStr(r); где r — переменная вещественного типа, вернёт:
Примеры работы с текстовыми файлами в Delphi
Чтение в переменную одного значения из файла:
Загрузить все строки файла в компонент Memo:
Следует отметить, что для этой задачи проще воспользоваться командой самого компонента Memo LoadFromFile().
Записать строку в файл:
Записать в текстовый файл все строки из компонента Memo:
Как и для чтения из файла в Memo, так и здесь, имеется специальная команда:
Файл — структура данных, находящаяся на носителе данных (энергонезависимом или энергозависимом).
Подробное рассмотрение работы с текстовым файлом «Delphi работа с файлами«.
Тип данных «запись».
Ещё более сложный тип данных delphi record — «запись». Внутри записи могут содержаться поля разного типа. Поэтому описание типа «запись» должно содержать информацию об адресе начала записи; о длине записи; список адресов начала полей, составляющих запись, и тип этих полей.
Объявляется запись следующим образом:
type tRec=record J:integer, sh:string[20]; ss:string; d:double; ar:array[1..3] of char; ex1,ex2:extended; end;
Нотация обращения к полям записи следующая:
vRec.sh:=’слово’; //не более 20 символов для короткой строки.
vRec.ss:=’предложение любой длины’; //длинная строка
vRec.d:=10.255; vRec.ex1:=456.89; vRec.ex2:=789.023;
Заметим, что полем может служить другая запись!
type tRec1=record JJ:integer, end;
type tRec=record J:integer, sh:string[20]; ss:string; d:double; ar:array[1..3] of char; ex1,ex2:extended; r1:tRec1 end;
Тогда для формирования значения JJ надо записать:
vRec.r1.JJ:=20;
Не прадо ли, очень похоже:
Form1.Memo1.Text ?
Теперь сделаем «петлю» и ещё раз вернёмся к типу «string».
Ещё раз о типе «string».
В типе «string» первые 12 байт служебные. В них указывается длина строки.
Номер кодовой таблицы символов (в какой язык интерпретировать числа, записанные в байтах, составляющих строку). Счётчик ссылок (он увеличивается на 1, когда выполняется s2:=s1, где s1 и s2 — строковые переменные).
Символы пронумерованы по порядку, начиная с 1. К символу номер N можно обратиться, записав s1[5]. Если, например, в s1 хранится слово «строка», то s1[4] вернёт символ «к».
На примере строки мы посмотрели, как усложняется описание типа. Непосредственно данным в памяти предшествует несколько байт, описывающих структуру этих данных.
Само обращение к данным происходит по ссылке (по адресу, который записан в переменной, объявленной как тип String).
Но и само описание структуры данных переменной сложного типа можно разместить отдельно от самих данных, оставив пере данными только ссылку на область памяти, где хранится описание (тип) структуры данных.
Записи являются как бы предшественниками такого типа данных, как объект.
Видео. Дописываем данные в конец файла.
Заключение.
Рассмотрено понятие «текстовый файл», организация данных внутри файла, дано понятие конца записи и конца файла. Даны операторы создания файловой переменной и её связывания с конкретным файлом, а также операторы записи в него строковой информации и закрытия файла.
Для чтения/записи текстовый файл надо открыть, при этом указатель установится на нулевую запись.
Оператор чтения строки считывает ровно одну запись. Весь текст считывается путём организации цикла.
Оператор AssignFile.
Этот оператор связывает файловую переменную и путь доступа к файлу. Формат оператора:
AssignFile(varF, «путь_доступа_к_файлу»)
Видео. Создаём форму для будущей программы.
Сохранение результатов расчётов.
В файле, как и в оперативной памяти, данные хранятся в виде нулей и единиц.
При записи какого-либо типа данных они превращаются в двоичный поток и записываются на диск.
При чтении с диска происходит обратный процесс. Благодаря тому, что известен тип записанных на диск данных, двоичный поток преобразуется в конкретный тип данных.
Предположим, мы прочитали с диска последовательные 32 бита (4 байта). Если файл описан как файл целого типа, то эти 4 байта будут интерпретированы как целое число.
Если файл хранит короткие строки (пример: type sh=char[20], то есть короткая строка — это массив символов. В короткой строке не может быть больше 255 символов),то байты будут интерпретированы как 4 символа.
То есть интерпретация содержимого, записанного на диск, зависит от описанного в программе типа файла.
Файл для хранения текста.
В delphi работа с файлами несколько различается в зависимости от того, надо ли записывать в файл произвольный текст, или это будет последовательность однотипных данных.
С текстовыми файлами мы сталкиваемся, например, создавая документ в программе «блокнот».
Для работы с текстовым файлом объявляется переменная:
var vMyTextFile:TextFile;
где TextFile – предопределённый тип файла.
Далее переменная связывается или с создаваемым на диске, или с существующим файлом. Например, мы хотим создать файл «D:\MyFile.txt».
Введём промежуточную переменную var s:string; и s:=»D:\MyFile.txt»; .
Свяжем переменную vMyTextFile c именем файла с помощью процедуры:
AssignFile(vMyTextFile, s);
Теперь, когда мы употребим переменную vMyTextFile в операторах чтения или записи, поток данных будет направлен в «D:\MyFile.txt».
Создадим файл процедурой:
Rewrite( vMyTextFile);
Если посмотреть в проводнике, то мы обнаружим наш файл «D:\MyFile.txt» с нулевой длиной.
Осталось заполнить его данными.
Замечание.
Если файл с таким именем и путём доступа уже существует на диске, то он будет уничтожен и создан заново с пустым содержанием.
Закрытие файла
По завершении работы с файлами, особенно в случае записи в них данных, необходимо корректно завершить работу с файловой переменной. Это делается для того, чтобы сохранить все внесенные в файл изменения.
Подключение к файлу
Для связи программы с файлом используется специальная переменная – "Файловая переменная". Объявляется она так же как и любая переменная в Delphi. Тип это переменной может быть File для типизированных (хранящих данные определенного типа) файлов, а можно указать TextFile, что будет означать тип обычного текстового файла. Объявление переменной:
В исполняемом коде программы выполняется подключение к внешнему файлу:
Команда AssignFile, выполняет связь файловой переменной с внешним файлом. Вторым параметром указывается адрес файла. Он может быть задан относительным или абсолютным. Если указать только имя файла, то программа будет пытаться обнаружить его в той же директории, где она сама и находится. Абсолютный путь указывается от корневого диска:
Использование относительной директории дает возможность не привязываться к конкретным дискам и адресам. Например:
После того как выполнено подключение, выполняется процедура, устанавливающая режим работы с файлом. В основном это режим чтения или записи. Эти режимы назначаются процедурами Reset() ( для чтения) и rewrite() (для записи):
* Для команды Rewrite() следует учитывать, что при ее выполнении, она либо создает файл, указанный в файловой переменной, либо если он уже есть перезаписывает файл заново, удаляя старый без какого-то предупреждения.
Любую из указанных команд можно использовать без команды AssignFile(). Для этого достаточно вторым параметром указать путь к файлу. Таким образом, она сразу выполнит привязку файла к файловой переменной и назначит режим работы с этим файлом:
Понятие «объект» как особый тип данных.
К полям записи обращаются по нотации «переменная_запись»«.»«имя_поля».
Такая же нотация характерна и для объекта. Вспомним, что компоненты Delphi — это объекты, встроенные в IDE (в среду разработки).
Но объекты принципиально отличаются от записей. Настолько же, насколько обычная переменная отличается от динамической.
Объекты содержат не только данные (которые в объекте называются полями), но и процедуры (и функции).
К этим процедурам можно обращаться с помощью всё той же нотации с «точкой», как и к полям с данными.
Например, вспомним, как мы очищали содержимое компонента Memo (удаляли из него весь текст).
Для этого мы использовали процедуру (в объектах встроенные процедуры называются методами!) Clear. Так как ей не нужны параметры, её можно писать без скобок, то есть вместо Clear() записать просто Clear.
Поэтому мы использовали следующее предложение:
Form1.Memo1.Clear;
Сам объект Memo1 создаётся по шаблону (типу) Tmemo.
Более того. Сами типы являются объектами, поставляемыми со средой IDE. В них содержится метод (процедура) Create, называемый конструктором.
Собственно, он и создаёт экземпляр объекта в программе по собственному образу и подобию. Объект — тип может быть только один в пределах видимости IDE. Но своих копий (экземпляров) он может создать сколько угодно (конечно, каждому экземпляру должно быть дано уникальное имя).
В программе экземпляр объекта оформляется как переменная объектного типа.
Здесь объявлены переменная Form1 три переменных типа Tmemo.
var Form1: Tform1; Memo1:TMemo; Memo2:TMemo; Memo3:TMemo; и так далее.
Tform1, Tmemo и другие встроенные в IDE объекты-типы называются Delphi компонентами. При размещении компонента на форму IDE вызывает конструктор объекта-типа автоматически при размещении компонента на форму.
При создании собственных объектов программист сначала конструирует тип—объект, а потом вызывает метод Create этого типа для создания экземпляра объекта.
Замечание. На будущее — типы, по которым создаются объекты, в объектном программировании называются «классами (Class)».
Позиционирование указателя типизированного файла.
Типизированный файл, в отличие от текстового файла, позволяет прочитать отдельную запись. Так как длина всех записей одинакова, их можно пронумеровать и обращаться к записи по номеру, наподобие одномерного массива.
Для обращения к записи по её номеру существует процедура позиционирования:
seek(файловая_переменная, номер_записи) //помним, что отсчет ведутся от 0)
Создадим файл для хранения целых чисел. Запишем в него 5 значений. Проконтролируем записанные значения чтением из файла и отображение их в memo.
Определим размер файла функцией FileSize(ф.п.).
Затем установим указатель файла в четвёртую позицию (то есть номер_записи=3).
Изменим значение записи в этой позиции и вновь проконтролируем результат.
Для решения задачи подготовим форму:
Воспользуемся полученной информацией и ещё раз посмотрим, как в delphi записать в файл данные фиксированной длины и какие процедуры и функции для работы с файлами нам для этого понадобятся.
Создадим обработчики событий для первой и второй кнопок:
var vFileInt:File Of Integer; // создаём переменную для ссылки на типизированный файл
const name=’d:\file1.int‘; //путь доступа к файлу
procedure TForm1.Button1Click(Sender: TObject);
rewrite(vFileInt); //создаём файл
j:=filePos(vFileInt); //контролируем положение указателя файла
write(vFileInt,j); //формируем значения и записываем их в файл.
j:=filePos(vFileInt); //опять контролируем положение указателя в файле
j:=fileSize(vFileInt); //проверяем размер файла (количество записей)
reset(vFileInt); //переоткрываем файл. При этом указатель файла устанавливается на 0.
while not EOF(vFileInt) do
read(vFileInt,j); //читаем файл и прочитанные значения отображаем в memo.
closeFile(vFileInt);
Форма после нажатия на первую кнопку:
procedure TForm1.Button2Click(Sender: TObject);
var j:integer; s:string;
reset(vFileInt);
seek(vFileInt,3); //устанавливаем указатель файла в четвёртую позицию (0,1,2,3)
write(vFileInt,j); //перезаписываем четвёртое значение
j:=filePos(vFileInt); //отображаем положение указателя файла после перезаписи.
reset(vFileInt);
while not EOF(vFileInt) do
read(vFileInt,j); //читаем и отображаем файл
closeFile(vFileInt);
Форма после нажатия на вторую кнопку:
Цикл чтения строк из текстового файла.
Так как с помощью процедуры ReadLn() можно прочитать только одну строку, то необходимо организовать цикл чтения строк из файла.
Он будет длиться до тех пор, пока не будет достигнут символ конца файла EOF.
Ранее мы уже рассматривали организацию цикла с помощью оператора for.
Но для его использования мы должны точно знать число его повторений. Для текстового файла это проблематично, поэтому удобней использовать цикл с так называемым пост условием:
repeat
«выполняемые операторы»
until условие
Если «условие» вырабатывает (возвращает) значение false, то цикл продолжается, если true — то завершается.
Или в нашем случае:
repeat
ReadLn(vMyTextFile,s);
Form1.Memo1.Lines.Append(s);
until EOF(vMyTextFile)
Войдя в цикл, выполняются находящиеся в нём операторы. Далее проверяется условие, находящееся в операторе until. Когдафункция EOF() вернётtrue(будет достигнут конец файла), цикл завершится и будет выполнен следующий за ним оператор.
Для примера напишем программу, на главной форме которой разместим новый компонент Panel, предназначенный для группировки на нём других компонент.
Чтение из текстового файла.
Чтобы организовать в delphi чтение из файла, его надо предварительно открыть процедурой Reset.
Эта процедура устанавливает внутренний указатель файла на нулевую запись.
Открытие файла осуществляется через файловую переменную: Reset(vMyTextFile).
Далее производится считывание записей от нулевой до последней оператором ReadLn( vMyTextFile, s1); , помещённым в цикл.
(Оператор ReadLn( vMyTextFile, s1 [, … , si, … , sn]) нет смысла использовать в таком виде, так как всё рано считывается ровно одна запись. То есть значение будет занесено только в s1, остальные переменные будут пустыми.).
Поэтому достаточно записать ( vMyTextFile, s1); и использовать этот оператор в цикле, отслеживая значение функции признака конца файла EOF(vMyTextFile).
При чтении последней записи из файла эта функция возвращает значение «true» — истина (служебное слово — предопределённая логическая константа. О логических константах и переменных и о том, как ими пользоваться, речь будет в дальнейшем. Другое возможное значение: «false» — ложь).
Замечание.
Использование «пустой» процедуры чтения в виде ReadLn( vMyTextFile) осуществляет переход к следующей записи.
Пример программы работы с текстовым файлом рассмотрен в видеоматериале.
Файловая переменная.
С помощью файловой переменной указывается тип файла.
- varF=TextFile; текстовый файл
- varF=File of тип_допустимый_для_типизированного_файла
Например: varF=File of integer; - varF=File; — нетипизированный файлж
Видео. Настраиваем свойства компонентов.
Читайте также: