Текстовые файлы в Delphi

А ты пиши мне письма мелким почерком, поскольку места мало в рюкзаке.

Фильменная песня

Романтическое создание писем при дрожащем пламени свечи, увы, безвоз­вратно ушло в прошлое. И хотя некоторые креативные приверженцы эпи­столярного стиля упорствуют в невежестве и доверяют свои невнятные мысли бумаге, последняя сейчас в основном используется по своему пря­мому назначению, то есть для складывания фигурок оригами и издания плакатов, призывающих беречь зелёного друга (коим для нас является лес, а не крокодил Гена и не пьяный товарищ).

 

Все наши винчестеры, флешки, диски CD- и DVD-ROM доверху забиты фай­лами. Каждый из них имеет имя и - почти всегда - расширение, которое следует за последней точкой в имени файла и обычно указывает на назна­чение файла и формат данных, хранящихся в нём.

 

Систематика файлов насчитывает многие сотни типов файлов: исполняе­мых exe, видео avi, mpg, звуковых ogg, wav, музыкальных mp3, mid, но, с точки зрения Delphi, разновидностей файлов всего 3: текстовые (они имеют тип TextFile), типизированные и нетипизированные.

 

На этом занятии мы рассмотрим текстовые файлы, которые состоят из строк, подобных тем, что мы изучили на прошлом уроке. Как в текстовых, так и в любых других файлах размещаются данные, которые можно сколь угодно долго хранить на диске даже после окончания работы с приложе­нием, в котором эти данные были созданы, а потом снова загрузить в него.

 

Наберите в самом простом текстовом редакторе любой сумбурный текст, который только придёт вам в голову, - его глубокий смысл только отвле­чёт нас от формы

Текстовые файлы в Delphi

Очень хорош для разбора текстовых файлов стандартный Блокнот, кото­рый не добавляет в файл никакой «отсебятины», в отличие от «продвину­тых» редакторов типа MS Word.

Не забудьте после набора текста нажать клавишу Return, чтобы завершить строку. Сохраните текст в файле под каким-нибудь именем - вот и готов настоящий текстовый файл! Обратите внимание, что к его названию авто­матически добавлено расширение .txt. Теперь вы можете открыть файл в любом редакторе и увидеть вашу строку в первозданном виде (естествен­но, все ваши труды по форматированию текста пойдут прахом, потому что никакая информация о ваших шрифтовых предпочтениях не сохраняет­ся!).

Когда мы изучали строки, то узнали, что разные типы строк по-разному хранятся в памяти компьютера. И вас, наверное, удивит тот факт, что на диске любые строки сохраняются одинаково, но не совсем так, как в ячей­ках памяти.

 

Если мы загрузим текст в редактирующую программу, то он будет разбит на строки так, как мы и его набирали. Но как редактор определяет конец строки? Может быть, вместе с каждой строкой записывается и её длина или после строки записывается нулевой символ? Второй вариант ближе к истине, но всё равно ошибочен.

В обычном текстовом редакторе мы никогда не увидим, что же там, в кон­це строки, поэтому воспользуемся таким текстовым редактором, который позволяет просматривать текст в 16-ричном виде, например, подойдёт WinHex

Текстовые файлы в Delphi

И вот мы видим: все символы строки записаны без всяких изменений, но в конце строки находятся сразу 2 символа - $0D и $0A (или то же самое в бо­лее привычном десятичном виде - #13 и #10). Они ещё в стародавние вре­мена обозначали возврат каретки принтера и переход на новую строку. Этот анахронизм сохранился до сих пор в текстовых файлах, которые ни­чего и не знают о принтерах.

 

Нам осталось узнать, как же записываются строки таким причудливым образом, поэтому рассмотрим основные операции с текстовыми файла­ми - сохранение их на диске и загрузку в приложение. Они не доставят вам хлопот, если вы будете точно следовать «рецепту».

 Независимо от того, сохраняем мы файл или загружаем его, первым де­лом нужно объявить файловую переменную типа TextFile:

var F: TextFile;

 

Её принято обозначать буквой F (от слова File, файл), но это необязатель­но. Именно эта переменная и будет псевдонимом реального файла.

 Затем нужно связать файловую переменную с именем файла, вос­пользовавшись процедурой

procedure AssignFile(var F: file; FileName: string);

Её легче понять на конкретном примере.

Вот так можно связать нашу файловую переменную с файлом «osh_frc_v.txt» (так как путь к файлу не указан, то файл должен находиться в той же папке, что и само приложение!).

AssignFile(F, 'osh_frc_v.txt');

или


 
var s: string;
s:= 'osh_frc_v.txt'; // строка s содержит имя файла AssignFile(F, s);

 Теперь можно открыть файл для чтения или записи.

Для считывания данных указанный файл должен существовать на диске. Чтобы открыть его, пользуемся процедурой

 

procedure Reset(var F: file); (в нашем примере - Reset(F); ) ,и можно загружать данные. Они будут считываться, начиная с первой строки.

 

Если файл уже был ранее открыт, то он сначала автоматически за­крывается, чтобы не потерять данные, а потом вновь открывается.

Чтобы сохранить данные в файле, воспользуемся процедурой

procedure Rewrite(var F: file); (в нашем примере - Rewrite(F); )

Она создаст новый файл с заданным именем и откроет его для записи. Будьте осторожны: если файл с таким именем уже имеется на диске, он будет уничтожен! Поэтому безопаснее записывать данные в существую­щий файл функцией

function Append(var F: Text): Integer; ( в нашем примере - Append(F); )

В этом случае новые строки будут добавлены в файл за последней стро­кой, так что все прежние данные не пострадают.

4. Для записи данных в файл служат процедуры

procedure Write(var F: file [; P1;  ...; Pn]);

procedure Writeln(var F: file [; P1;     ...;     Pn]);

В квадратных скобках записаны необязательные параметры, которые яв­ляются выражениями следующих типов: char, string, PChar, integer, real, boolean. Таким образом, в текстовый файл можно записывать не только символы, слова, строки, но и числа (при записи выражений логического типа в файл выводятся слова TRUE и FALSE). Количество выражений в списке вывода может быть любым.

Если в одной строке файла процедурой Write сохраняются данные разных типов, то они будут записаны друг за другом без пробелов и других разде­лителей. Процедура Writeln делает то же самое, но затем закрывает стро­ку в файле (добавляет в конец строки символы $0D$0A).

Например, процедура

Writeln(F, ’А ты пиши мне письма мелким почерком!’);

Запишет строку в кавычках (но без кавычек!). Или то же самое:


var s: string;
s:= ’А ты пиши мне письма мелким почерком!’;
Writeln(F, s);

Или


var s1,s2,s3,s4,s5,s6,s7: string; s1:= ’А ’;
s2:= ’ты ’; s 3:= ’пиши ’; 
s4:= ’мне ’; s5:= ’письма ’; s 6:= ’мелким ’; s7:= ’почерком!’;
 
Writeln(F, s1,s2,s3,s4,s5,s6,s7);

Или

Writeln(F, ’А ’, ’ты ’, ’пиши ’, ’мне ’, ’письма ’, ’мелким ’, ’почерком!’);

Или

Writeln(F, ’А ’ + ’ты ’ + ’пиши ’ + ’мне ’ + ’письма ’ + ’мелким ’+ ’почерком!’);

 

Вы также можете смешивать константы и переменные:

Writeln(F, si + ’ты ’ + s3 + ’мне ’ + s5 + ’мелким ’ + s7);

Если у вас есть к тому большая нужда, вы можете записать в строку числа и логические константы:

Writeln (F, si + ’ты ’   + s3 + ’мне ’  + s5 + ’мелким ’ + s7, ’    ’,123, ’    ’,   321, ’    ’,   123 < 321);

 

Тогда на диске появится строка:

 

А ты пиши мне письма мелким почерком!

123 321 TRUE

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

 

Процедура только с одним параметром - Writeln(F) - просто завер­шает строку, ничего в неё не записывая.

 

Процедуры Writeln и Write начинают записывать данные с первой строки файла, затем Writeln (!) последовательно переходит ко вто­рой строке, третьей - и так далее до конца файла. С их помощью нельзя сохранить данные в произвольной строке файла, но можно записать нужное число пустых строк процедурой Writeln(F), а уже затем записать нужную строку.

 

Для чтения данных из текстового файла имеются процедуры:

procedure Read(var F: file [; V1;   ...; Vn]);

В квадратных скобках записаны необязательные параметры, которые яв­ляются переменными следующих типов: char, string, integer, real, PChar. Количество переменных в списке ввода может быть любым.

 

Мы чаще будем использовать вторую процедуру (Readln) - чтобы считать целиком всю строку в указанную строковую переменную:


var
s: String;
Readln(F, S);

Если в одной строке записаны данные других типов через пробел, напри­мер, «123 321 TRUE», то их можно считать так:


var
s : String; n,m:integer;
Readln(F, n, m, s);

В результате выполнения этой операции значением целой переменной n будет число 123, целой переменной m - число 321, строковой переменной s - строка 'TRUE' (нельзя считать значение в логическую переменную!).

 

Не забывайте следить за соответствием типов переменных и считываемых данных, иначе возникнет ошибка!

 

Если процедура Readln считывает только часть данных из строки (в списке ввода меньше переменных, чем в строке), то оставшаяся часть строки будет пропущена.

Если переменные при вызове процедуры отсутствуют - Readln(F);, - то текущая строка в файле пропускается и далее считываются дан­ные из следующей строки.

 

Если строка считывается в переменную типа короткой строки или PChar и имеет больше символов, чем указанная максимальная длина строки, то вводимая строка усекается.

При вводе символа из файла в переменную типа char читается только 1 символ, в том числе и коды конца строки.

 

 

Процедуры Read и Readln начинают считывать данные с первой строки файла, затем Readln (!) последовательно переходит ко вто-рой строке, третьей - и так далее до конца файла. С их помощью нельзя считать данные из произвольной строки файла, но можно пропустить нужное число строк процедурой Readln(F), а уже затем считать нужную строку.

 

5. После завершения операций с файлом он должен быть закрыт процеду­рой:

procedure CloseFile(var F: file);(в нашем примере - CloseFile(F); )

Никогда не забывайте одну из заповедей программирования: Уходя, гаси­те свет!

������� ������ ��� dle ������� ��������� ������

Помоги проекту! Расскажи друзьям об этом сайте: