Delphi while not eof - IT Справочник
Llscompany.ru

IT Справочник
53 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Delphi while not eof

Delphi while not eof

Есть примерно такой код:

while not DataSet.Eof do
begin
with DataSet do
begin
Line := Fields[0].AsString;
for i:= 1 to FieldsCount — 1 do
Line:= Line + #9 + Fields[0].AsString;
writeln(f, Line);
Next;
end;
end;

Непоняностей две:
1. Почему это безобразие выполняется ок. 8 мин (22000 записей)
2. Скорость падает по мере вызова Next (к концу DataSet примерно в 3 раза)

Обидно то, что сам Access делает экспорт в файл секунд за 10-15.

PS
Delphi 6, ADO, Access
Настройки ADO-компонент — по умолчанию.


sniknik ( 2002-11-27 19:28 ) [1]

так им (Access-ом) и делай. и быстрее и без ошибок 🙂 Line:= Line + #9 + Fields[ ].AsString;

примерный запрос
SELECT * INTO Test#Txt IN «D:» «Text;» FROM TableInAccess

Delphi 6, ADO, Access
Настройки ADO-компонент на Jet. где ты взял по умолчанию?


Diouzshev ( 2002-11-27 19:35 ) [2]

For sniknik © (27.11.02 19:28)

>так им (Access-ом) и делай. и быстрее и без ошибок 🙂 Line:= >Line + #9 + Fields[0].AsString;
Ctrl+C Ctrl+V, сам знаешь %)

>примерный запрос
>SELECT * INTO Test#Txt IN «D:» «Text;» FROM TableInAccess
Ссылка на доку по этой теме есть?
А обратно можно? (в базу)

>Настройки ADO-компонент на Jet. где ты взял по умолчанию
ещё надоедливый LoginPromt %)


sniknik ( 2002-11-27 19:41 ) [3]

>А обратно можно? (в базу)
конечно, анологично, поменяй местами in и out.

дока
D:Program FilesCommon FilesMicrosoft SharedOffice101049JETSQL40.CHM
см куда Мс Офис ставил.

надоедливый LoginPromt отключается в ADOConnection.LoginPromt:= False.


Diouzshev ( 2002-11-27 20:28 ) [4]

>надоедливый LoginPromt отключается в ADOConnection.LoginPromt:= False.

Это было отличие от настроек по умолчанию %))


Diouzshev ( 2002-12-03 15:04 ) [5]

Проблема была решена очисткой свойства IndexFieldName (не все было по умолчанию %< ), время сократилось до 40 секунд, имхо - это приемлемо.


sniknik ( 2002-12-03 15:28 ) [6]

нет пределов совершенству! :о)

запрос Access-а (вернее Jet-а) на переброску в текст
SELECT * INTO Test#Txt IN «D:» «Text;» FROM plucash
Выполнено применительно к 52798 записям. (no recordset)
выполняется 13.5 сек.
plucash — таблица dBase IV (подключение через jet тоже к нему)
24 поля, обший размер полей 429 байт. win2000, celeron 1000

то же самое из Access (mdb) в Text 11 сек.
сравнивай.


Diouzshev ( 2002-12-03 16:14 ) [7]

Все так, но проблема с Next меня интересовала из принципа :)) — не всегда спасает SELECT * INTO

про SELECT * INTO я понял уже давно и успешно применил 🙂 (за что спасибо)

Конец файла

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

Для определения конца файла можно воспользоваться функцией EOF (End of File — конец файла). У функции EOF один параметр — файловая переменная. Значение функции EOF равно False, если прочитанный элемент данных не является последним в файле, т. е. возможно дальнейшее чтение. Если прочитанный элемент данных является последним, то значение EOF равно True.

Значение функции EOF можно проверить сразу после открытия файла. Если при этом оно окажется равным True, то это значит, что файл не содержит ни одного элемента данных, т. е. является пустым (размер такого файла равен нулю).

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

Рис. 7.6. Окно программы Чтение из файла

Листинг 7.5. Чтение из файла

Windows, Messages, SysUtils, Variants, Classes,

Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons;

procedure Button2Click(Sender: TObject);

procedure ButtonlClick(Sender: TObject); private

// щелчок на кнопке Открыть

procedure TForm1.Button1Click(Sender: TObject);

f: TextFile; // файл fName: String[80]; // имя файла

buf: String[80]; // буфер для чтения из файла

fName := Edit1.Text; AssignFile(f, fName); <$!->

Reset(f); // открыть для чтения <$I+>

if IOResult <> 0 then begin

MessageDlgt’Ошибка доступа к файлу ‘ + fName,

mtError,[mbOk],0); exit; end;

Читать еще:  Внеочередная поверка си проводится в случаях

// чтение из файла

readln(f, buf); // прочитать строку из файла

Memo1.Lines.Add(buf); // добавить строку в поле Memo1

CloseFile(f); // закрыть файл

// щелчок на кнопке Сохранить — запись в файл

procedure TForml.Button2Click(Sender: TObject);

f: TextFile; // файл

fName: String[80]; // имя файла

fName := Edit1.Text; AssignFile(f, fName);

Rewrite(f); // открыть для перезаписи

for i:=0 to Memo1.Lines.Count do // строки нумеруются с нуля

CloseFile(f); // закрыть файл

MessageDlg(‘Данные записаны в файл ‘,mtlnformation,[mbOk],0);

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

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

Добавление очередной прочитанной из файла строки в поле Memo выполняется применением метода Add к свойству Lines.

Создание и работа с текстовыми файлами в Delphi

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

Итак, в общем виде, работа с файлом заключается в следующих этапах:

1. подключение к файлу – связь с внешним файлом, указание режима подключения;

2. выполнение операций записи в файл или чтения из файла;

3. завершение работы с файлом.

Подключение к файлу

Для связи программы с файлом используется специальная переменная – «Файловая переменная». Объявляется она так же как и любая переменная в Delphi. Тип это переменной может быть File для типизированных (хранящих данные определенного типа) файлов, а можно указать TextFile, что будет означать тип обычного текстового файла. Объявление переменной:

var
f : TextFile;

В исполняемом коде программы выполняется подключение к внешнему файлу:

Команда AssignFile, выполняет связь файловой переменной с внешним файлом. Вторым параметром указывается адрес файла. Он может быть задан относительным или абсолютным. Если указать только имя файла, то программа будет пытаться обнаружить его в той же директории, где она сама и находится. Абсолютный путь указывается от корневого диска:

Использование относительной директории дает возможность не привязываться к конкретным дискам и адресам. Например:

AssignFile(f, ‘datainput.txt’ ); // во вложенной папке относительно директории с программой
AssignFile(f, ‘..input.txt’ ); // на уровень выше директории с программой
AssignFile(f, ‘..datainput.txt’ ); // во вложенной папке на уровень выше директории с программой

После того как выполнено подключение, выполняется процедура, устанавливающая режим работы с файлом. В основном это режим чтения или записи. Эти режимы назначаются процедурами Reset() ( для чтения) и rewrite() (для записи):

* Для команды Rewrite() следует учитывать, что при ее выполнении, она либо создает файл, указанный в файловой переменной, либо если он уже есть перезаписывает файл заново, удаляя старый без какого-то предупреждения.

Любую из указанных команд можно использовать без команды AssignFile(). Для этого достаточно вторым параметром указать путь к файлу. Таким образом, она сразу выполнит привязку файла к файловой переменной и назначит режим работы с этим файлом:

Reset(f, ‘C:myproginput.txt’ ); // чтение
Rewrite(f, ‘C:myproginput.txt’ ); // запись

Операции с файлами

Для чтения из файла, необходимо назначить режим чтения и использовать команду Readln(), которая будет вводить в строковую переменную по одной строке из файла. Затем с этой переменой можно выполнить необходимые действия.

Обычно для загрузки всех строк из файла используется оператор цикла. Для того, чтобы определить, что файл закончился используется функция EOF() (End Of File). Таким образом получается цикл, в котором последовательно в строковую переменную вводятся все строки файла и завершающийся после окончания фала:

while ( not EOF(f)) do begin
Readln(f, s);
end ;

Для записи, назначение режим записи в файл и командой Writeln() производится запись по строкам.

Закрытие файла

По завершении работы с файлами, особенно в случае записи в них данных, необходимо корректно завершить работу с файловой переменной. Это делается для того, чтобы сохранить все внесенные в файл изменения.

Читать еще:  Css text wrapping

Примеры работы с текстовыми файлами в Delphi

Чтение в переменную одного значения из файла:

var
f : TextFile;
s : String;
begin
AssignFile(f, ‘input.txt’ );
Reset(f);

Загрузить все строки файла в компонент Memo:

var
f : TextFile;
s : String;
begin
AssignFile(f, ‘input.txt’ );
Reset(f);

while ( not EOF(f)) do begin
Readln(f, s);
myMemo.Lines.Add(s);
end ;

Следует отметить, что для этой задачи проще воспользоваться командой самого компонента Memo LoadFromFile().

Записать строку в файл:

var
f : TextFile;
begin
AssignFile(f, ‘input.txt’ );
Rewrite(f);

Writeln(f, ‘My text’ );

Записать в текстовый файл все строки из компонента Memo:

var
f : TextFile;
i : Integer;
begin
AssignFile(f, ‘input.txt’ );
Rewrite(f);

for i := 0 to myMemo.Lines.Count — 1 do
Writeln(f, myMemo.Lines[i]);
CloseFile(f);
end ;

Как и для чтения из файла в Memo, так и здесь, имеется специальная команда:

Цикл while Delphi

Поговорим еще об одной инструкции — инструкции while Delphi, обеспечивающей реализацию цикла. Инструкция while Delphi применяется тогда, когда некоторая последовательность действий выполняется несколько раз, при этом необходимое количество повторений в процессе разработки программы заранее не известно (его можно определить лишь в момент работы программы).

В качестве примеров на применение цикла while можно считать вычисление с заданной точностью (например, eps=0.000001), осуществление поиска в массиве, поиск в файле. Общий вид инструкции while Delphi представляется следующим образом:

откуда условие означает выражение типа Boolean, устанавливающее условие, при котором будут выполнены инструкции цикла.

Последовательность выполнения инструкции while в Delphi такова:

  1. Вначале происходит вычисление значения выражения условие;
  2. Если условие принимает значение False (значение Ложь — условие не выполнено), то инструкция while завершает свое выполнение;
  3. В случае значения True (значение Истина — условие выполнено) осуществляется выполнение инструкций тела цикла, находящихся между служебными словами begin и end. Далее вновь проводится проверка выражения условия. Если и это условие выполнено, то вновь повторяются инструкции цикла, расположенные между зарезервированными словами begin и end. Так будет продолжаться до тех пор, пока значение выражения условие не примет значение False.

Алгоритм, реализующий инструкцию while, проиллюстрирован на рисунке ниже:

Пример программы на цикл while Delphi:

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

Основу алгоритма составляет тот факт, что сумма числового ряда: 1 — 1/3 + 1/5 — 1/7 + 1/9 + … стремится к числу ПИ/4 с большим числом элементов. Нетрудно определить n-й член рассматриваемого числового ряда: An = 1/(2*n — 1).

Знак «-» ставится перед очередным элементом ряда, если n представляет собой четное число — это можно установить делением числа n на 2: если остаток от деления равен нулю — n четно, в противном случае число n является нечетным. Вычисление значения числа ПИ заканчивается в том случае, если значение некоторого члена ряда меньше заданной точности вычисления. Диалоговое окно программы в процессе ее работы представлено иллюстрацией ниже:

Как Вы можете заметить, пользователь сначала осуществляет ввод в поле Edit1 точности вычисления. При нажатии пользователем на командную кнопку Вычислить (Button1) программа производит вычисление значения числа ПИ и впоследствии выводит полученный результат в поле метки Label1. Листинг данной программы Вы можете скачать по этой ссылке.

While Not EOF(F) dans Thread [Résolu]

J’ai un souci avec la détection d’une Fin de lecture de fichier dans un Thread:

1. Code qui marche :
Je détecte la Fin du parcours de Fichier avec le compteur Interne

2. Code qui ne marche pas
Détection classique de Fin de fichier par EOF(F) en remplacement du Booléen précédent Fin Trait

Le Thread continue sa progression sur Inc(FCount) et ne s’arrête jamais.
J’ai donc l’impression que le EOF n’est pas pris en compte par le Thread Créé.

Question:
1. Dans ce cas, comment se prémunir d’une éventuelle erreur de lecture au delà de la fin de fichier.
Ce qui est bizarre, c’est que mon compteur continue bien au-delà de la valeur du fichier mais ne produit pas d’erreur
2. Ma préférence serait de mettre ma boucle de lecture de Fichier dans la Fiche et d’envoyer au thread, les variables dont il a besoin pour l’affichage. mais je ne sais pas si c’est valable .

Je progresse mais pas facile à maitriser ces threads. Merci pour vos éclairages.

Читать еще:  Delphi убрать пробелы из строки

9 réponses

j’ai testé et en changeant:

ça fonctionne très bien .. enfin chez moi testé sous D7 & D2009
mais à ta place j’utiliserai les Streams et non AssignFile !!

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

251 internautes nous ont dit merci ce mois-ci

mets aussi AssignFile avant try :

si l’assignation échoue il n’est pas utile fermer F (Close(F)) puisque non assigné.

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

251 internautes nous ont dit merci ce mois-ci

. mais le teste je l’ai fait avec ton code hein (pas avec les Streams)!!
as-tu déjà essayé, dans ton code, de remplacer «string» par «Char» ?

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

251 internautes nous ont dit merci ce mois-ci

Salut,
l’utilisation de Read et de string dans un fichier texte même en utilisant SetLineBreakStyle est. en gros tu rentres dans un fichier qui ne te donnera jamais de marqueur de fin,donc tu rentres dans une boucle infinie ! Readln te permet d’avoir des marqueurs de fin correcte et de ne pas rentrer dans cette boucle. remplacer string par char permet de faire ce que tu veux,mais caractère par caractère et donc d’arriver à la fin du fichier,mais en terme de performance c’est vraiment pas top.
Pour te convaincre voici une boucle infinie avec Read et un fichier texte de 2 lignes :

procedure TForm1.Button1Click(Sender: TObject);
var
F : TextFile;
S : string;
begin
AssignFile(F,ExtractFilePath(Application.ExeName)+’Test.txt’);
Reset(F);
while not eof(F) do
begin
Read(F,S);
ListBox1.Items.Add(S);
end;
CloseFile(F);
ShowMessage(‘Fin fichier’);
end;

Moi je ferais comme cirec en utilisant les streams.
Bon courage @+yanb

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

251 internautes nous ont dit merci ce mois-ci

Merci de m’avoir répondu.
Non Readln ne change rien, d’ailleurs avec un Fichier texte, il vaut mieux utiliser readln.
Je pense que le problème vient du fait que les procédures et méthodes de la VCL sont en réalité incluses dans le Thread principal de l’application.
D’où mon intérêt supplémentaire pour essayer de mettre la boucle princiale dans une procédure de la Fiche. Mais c’est une autre structure que celle que je met ici dans ce post.
En attendant, je peux gérer le parcours de mon fichier dans le exécute du Thread par un boolean.
. Je vous tiens au courant. J’attends de résoudre ce problème pour publier mon code.
Beaucoup d’exemples fictifs de thread sur les sites mais peu de réels applis même simplifiées.

Merci Cirec, Oui le AssignFile avant le try, ok!
je vais essayer avec les stream.

oui on le sait que c’est très long . mais le but de cette «procédure» c’est justement d’avoir une procédure longue afin de faire une démo concrète de l’utilisation d’un Thread (cf. son code):
» FMessage := ‘Traitement Long en cours. ‘;»

Merci pour vos commentaires. Je réponds dans l’ordre.

1. Effectivement, ça marche avec un type Char. Mais pour la démo, j’utilisai un TextFile car ça me paraissait plus rapide de ligne par ligne. Comme quoi!

2. Dans un Fichier Texte, mieux vaut Utiliser Readln effectivement et je suis d’acord que les performances ne sont pas au rendez-vous.

3. Les Stream sont la solution. Commme je vais avoir de nombreux fichiers à analyser dont certains seront assez volumineux, j’ai développé une structure particulière pour mes besoins.

Méthode que je pense adopter :
1. J’ouvre le fichier de travail avec un FileStream 2. Je le copie par bloc dans un memoryStream
(dans le code ci-dessous, un bloc = 1 ligne du fichier)
3. Je procède aux vérifications (ici test de longueur), comptabilité des erreurs constatées et
affichage des progressions et messages

4. Je créée une image du fichier dans un TList afin
pour l’exemple de le trié par ordre alphabétique rapidement

Voilà où j’en suis. ça ne parait pas pas très optimisé. Je vais devoir choisir entre le mémoryStream et la TList me semble t-il. Utiliser les deux parait surfait.

Ссылка на основную публикацию
ВсеИнструменты 220 Вольт
Adblock
detector