Delphi очистить текстовый файл

Обновлено: 04.07.2024

var F: File ;

Описанная таким образом файловая переменная считается нетипизированной, и позволяет работать с файлами с неизвестной структурой. Данные считываются и записываются побайтно блоками, размер которых указывается при открытии файла, вплоть от 1 байт.

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

var F: File of тип_записи ;

В качестве типа могут использоваться базовае типы, или создаваться свои. Важно только, чтобы для типа был точно известен фиксированный размер в байтах, поэтому, например, тип String в чистом виде применяться не может, а только в виде String[N], как указывалось в уроке Delphi 5.

Данные, считанные из файла или записываемые в файл, содержатся в обычной переменной, которая должна быть того же типа, что и файловая. Поэтому сначала в программе лично я описываю нужный тип, а затем ввожу две переменные этого типа - файловую и обычную:

Описание файловой переменной


Для текстовых файлов отдельно укажу, что тип файловой переменной в этом случае TextFile, а тип обычной - String.

Для открытия файла нужно указать, где он расположен. Для этого файловая переменная должна быть ассоциирована с нужным файлом, который определяется его адресом. Адрес файла может быть абсолютным, с указанием диска и каталогов ('C:\Мои документы\Мои рисунки\FileName.ini'), или относительным, тогда он создаётся в папке с .exe файлом программы. Для задания относительного адреса достаточно указать имя файла с нужным расширением. Делается это оператором AssignFile :

AssignFile(SaveF, 'C:\Мои документы\Мои рисунки\FileName.ini');
AssignFile(SaveF, 'FileName.ini');

Теперь файл должен быть открыт.
Открытие файла оператором Rewrite приведёт воссозданию файла заново, т.е. существующий файл будет без предупреждения уничтожен, и на его месте будет создан новый пустой файл заданного типа, готовый к записи данных. Если же файла не было, то он будет создан.
Открытие файла оператором Reset откроет существующий файл к считыванию или записи данных, и его указатель будет установлен на начало файла :

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

Rewrite(SaveF, 1);
Reset(SaveF, 1);

Чтение файла производится оператором Read :

Запись в файл производится оператором Write :

При этом чтение и запись производится с текущей позиции указателя, затем указатель устанавливается на следующую запись. Можно проверить, существует ли нужный файл, оператором FileExists :

if FileExists('FileName.ini')
then Read(SaveF, SaveV);

Принудительно установить указатель на нужную запись можно оператором Seek(SaveF, N), где N - номер нужной записи, который, как и почти всё в программировании, отсчитывается от нуля:

Seek(SaveF, 49); - установка указателя на 50-ю запись.

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

while (not EOF(SaveF)) do
Read(SaveF, SaveV);

Для текстовых файлов вместо Read и Write используются операторы Readln и Writeln, умеющие определять конец строки. приведена процедура чтения текстового файла.

Оператор Truncate(SaveF) позволяет отсечь (стереть или, если хотите, удалить!) все записи файла, начиная от текущей позиции указателя, и до конца файла.

В конце работы с файлом его необходимо закрыть. Это делается оператором CloseFile(SaveF) ;

Теперь можно изменить программу из первой части урока, запоминающую своё положение на экране. Описание переменных опускаю, оно приведено на рисунке выше.

Создаём обработчик события Формы OnCreate со следующим содержимым:

procedure TForm1.FormCreate(Sender: TObject) ;
begin
AssignFile(SaveF, 'Init.ini') ;
if FileExists('Init.ini') then
begin
Reset(SaveF) ;
Read(SaveF, SaveV) ;
Form1.Left := SaveV.X ;
Form1.Top := SaveV.Y ;
Form1.Caption:=SaveV.Caption ; //Наши переменные дополнительно сохраняют заголовок Формы!
end ;
end ;

Теперь необходимо создать обработчик события OnClose :

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction) ;
begin
Rewrite(SaveF) ; //Нет необходимости проверять наличие файла, создадим его заново!
SaveV.X := Form1.Left ;
SaveV.Y := Form1.Top ;
SaveV.Caption := Form1.Caption ;
Write(SaveF, SaveV) ;
CloseFile(SaveF) ;
end ;

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

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

Я использую тип TextFile, а не TFileStream. Добавить, переписать и закрыть файл, чтобы открыть файл.

Если вы используете AssignFile для открытия файла (по мере того, как ваше редактирование появляется), вы можете использовать Rewrite :

Мне кажется, что тема начинается немного смутно с тем, что он хочет и что произойдет в системе.

Требование: мне нужно удалить. содержимое. файла. не удалив файл сначала, а затем создав новый. Чтобы избежать ошибок, когда лицо перед монитором все еще открывает этот текстовый файл. Просто удалите содержимое файла, а затем добавьте новый текст строки.

Однако в другом ответе используется ReWrite который, начиная с самого ReWrite Turbo Pascal 1.0, делает именно то, что, по словам главы, он хочет избежать - удаление старого файла.

Ну, так как стирание файла в порядке для темы, то я бы хотел представить несколько простых способов сделать это - несколько oneliners.

Тот, который использует запас Delphi,

Это делает такую же последовательность создания-удаления, как ReWrite но требует меньше шаблона.

Также можно действительно отказаться от содержимого файла, не удаляя его сначала, но это требует явного открытия существующего файла и явного отказа от его содержимого. Изменив другой ответ, чтобы избежать удаления, это будет

на основе старых функций Паскаля

Тогда, возможно, возникает проблема одновременного доступа к файлам - упомянутая ошибка, когда лицо перед монитором все еще открывает этот текстовый файл.

Прежде всего, если человек читает файл в "Блокноте", это не означает, что файл ОТКРЫТО - это едва ли означало, что файл ОТКРЫТО, ЧИТАЕТ И ЗАКРЫТ. Однако, если человек читает файл в Microsoft Word, то, вероятно, файл действительно ОТКРЫВАЕТСЯ ПРЯМО СЕЙЧАС. Так как Windows делает небольшую разницу между файлом и его именем, в последнем случае желаемое удаление файла было бы невозможным с использованием обычных ОС.

Но это еще не все. Дело в том, что когда какая-то программа открывает файл, она также указывает на ее спрос на ограничения доступа к файлам. Даже если программист не просил об этом явно, он просто должен заявить о своих намерениях ОС, используя некоторые значения по умолчанию. И можно проверить его в источниках Delphi RTL. Если мы подумаем об упомянутом выше случае, когда другой пользователь имеет файл, открытый в MS Word, то по умолчанию файл будет открыт в fmShareDenyWrite. Другие приложения могут открывать файл для чтения, но не для записи. Режим.

И это означает, что сама попытка открыть файл в режиме чтения + записи (вызов ReSet ) завершится неудачно, это будет своего рода нарушение доступа на уровне файловой системы. То же самое произошло бы, если бы в topicstarter попытался ReSet для чтения + записи файла с CD-ROM или из некоторого сетевого ресурса только для чтения. Из-за того, что topicstarter все еще способен изменять FileMode и делать FileMode для чтения только для ReSet . Однако. однако тогда файл будет открыт в режиме только для чтения, а это означает, что удаление содержимого файла (вызов Truncate ) было бы более невозможным.

Что ж, что произойдет, если какое-нибудь экзотическое приложение Viewer откроет файл, он прочитает его до строки 1234 (и там будет свой "курсор"), а затем наша программа отключит все содержимое и сделает файл состоящим всего из 12 короткие линии? то неожиданно Viewer будет иметь недопустимое расположение в файле и больше не сможет читать его без какого-либо пути восстановления ошибок, который заново откроет файл или, по крайней мере, перечитает его с самого начала. Однако если разработчик Viewer не закодировал этот конкретный код восстановления ошибок, тогда средство просмотра просто потерпит крах.

Таким образом, в целом, тема-руководитель должен подумать о своем подходе к параллельному доступу к файлам (совместному использованию):

Я попытался использовать эту кодировку для выполнения задачи:

но я не уверен, что поместить в пространство "индекс".

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

так в вашем примере, вот так

это может быть медленно для больших файлов, как циклы IndexOfName, хотя каждая строка в TStringList и проверяет каждую строку по очереди, пока не найдет совпадение.

отказ от ответственности: протестировано / работает с Delphi 2007, Delphi 7 может быть различным.

я не понимаю, почему так много людей делают это так сложно. Это довольно просто:

как Ариох там говорит, Если вы сохраните с тем же именем файла, вы рискуете потерять свои данные при этом сэкономить не удастся, так что вы можете сделать что-то вроде

это сохраняет резервную копию исходного файла как FileName + '.old' .

объяснениями

работает назад

зачем работать в обратном направлении? Потому что если у вас есть следующие пункты

и вы удаляете элемент в ^ , то следующие элементы будут смещаться вниз:

если вы повторите вперед, теперь вы укажете на

и E никогда не исследовал. Если вы пойдете назад, то вы укажете на:

отметим, что E , F и G были осмотрены уже, так что теперь вы действительно рассмотрите следующий пункт, C и вы не пропустите ни. Также, если вы идите вверх, используя 0 to Count - 1 и удалить Count станет одним меньше, и в конце вы попытаетесь получить доступ за границу списка. Это не может произойти, если вы работаете в обратном направлении, используя Count - 1 downto 0 .

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

поэтому вам лучше просто сделать это явно.

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

Примечание 1: см., если проверка имени пользователя должна быть чувствительной к регистру или случай-игнорирование:

примечание 2: в Delphi 7 SizeOf( s[1] ) всегда равно единице, потому что string - это псевдоним для AnsiString . Но в более новой версии Delphi это не так. Это может показаться утомительным и избыточным, но это может сэкономить много головной боли в будущем. Еще лучше бы быть иметь временное AnsiString введите переменную типа a := AnsiString( s + ^m^J ); fs.WriteBuffer(a[1],Length(a));

до сих пор все предлагали использовать для For..Тогда цикл, но могу ли я предложить повторить..В то время как.

традиционный For..Петля является хорошим вариантом, но может быть неэффективным, если у вас есть длинный список имен пользователей (они обычно уникальны). После обнаружения и удаления на цикл продолжается до конца списка. Это нормально, если у вас есть небольшой список, но если у вас есть 500 000 пользователей и вы хотите в позицию 10 000 нет смысла продолжать дальше.

поэтому попробуйте это.

после вызова функция возвращает True или False, указывая, что имя пользователя было удалено или нет.

просто для удовольствия, вот компактное решение, которое мне нравится за его читаемость.

очевидно, это не самое эффективное решение. Это может выполняться быстрее, не добавляя отдельные элементы в массив или кэшируя строку поиска.

для тех, кто любит шутки. Это тоже работает:

объяснение

  1. он загружает содержимое файла в строку.
  2. строка отправляется в TRegEx.Заменить
  3. регулярное выражение ищет имя пользователя, за которым следует знак хэша, затем любой символ, а затем CRLF. Он заменяет его пустой строкой.
  4. полученная строка затем записывается в оригинал файл

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

Пожалуйста, выделяйте текст программы тегом [сode=pas] . [/сode] . Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля. Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
. (продолжение следует) .
Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.
Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца.

Всем спасибо кто мне сегодня помогал. Вы просто умницы, такие программы пишете, просто заглядение. Очень благодарна. На последок вопросик. У меня такия проблема. как очистить файл после того как в него что то записалось. Ну вот например: Открыли файл, поработали с данными в нём и теперь результат записываем в новый файл. Но вот беда. Каждый раз когда запускаешь программу данные в новый файл приписываются, т.е. прибавляются к уже существующим. как можно сделать, чтобы файл был чистым когда я снова запускаю прогу.
Файл это документ .txt



Самый простой вариант, это удалить старый файл при создании нового файла.





Что такое ссылка? Если открыть файл через проводник, то в FAQ.



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

Как известно, файлы имеют различные форматы и к ним применяются различные программы для обработки. Например, файлы рисунков BMP, текстовые файлы TXT и т.п. Файлы имеют различные имена и определенное расширение, имеющее в среде MS-DOS максимально три символа. Если у файла расширение RAR, то пользователь и операционная система знает, что это архиватор, причем windosw для обработки этого файла применяет средства, указанные в специальном разделе реестра.

Копирование файлов

Для копирования файлов применяется функция CopyFile. Формат ее такой:

CopyFile является функцией, которая возвращает флаг успешной или нет операции копирования.

Например, следующая строка:

Перемещение файлов

Для перемещения файлов применяется функция MoveFile. Она имеет следующий формат:

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

Переименование файлов

У всех вышесказанных командах параметры исходного и конечного файла имеет тип PChar. Это строковый тип с завершающимся нулем. Возможно, вы раньше слышали о таком формате строковых данных. В такую переменную можно занести строку очень большой длины. Ее размер ограничивается наличием нулевого байта в конце. Теоретически такая переменная может иметь бесконечный размер. На практике она ограничивается размерами выделяемой памяти для программы (2Гб).

Преобразование обычной строковой переменной, типа String в PChar производится функцией:

При этом, для команд файловых операций возможны объединение строк. Например:

procedure TForm1.Button1Click(Sender: TObject);

Var InDir,OutDir:String; // объявление строковых переменных

InDir:='c:\1\'; // каталог исходных файлов

OutDir:='c:\2\'; // каталог записуемых файлов

Здесь налицо операция соединения двух строковых переменных.

В итоге этой процедуры будет копирование файлов c:\1\1.txt и c:\1\2.txt в каталог c:\2. Файлы копируются под теми же именами.

Удаление файлов

Работа с текстовыми файлами. Чтение из текстового файла

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

Все это благодаря свойству Lines, в котором хранятся строки.

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

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

Varf:TextFile; // объявление файловой переменной

st:String; // строковая переменная

AssignFile(f,'c:\1.txt'); // привязка названия файла к файловой переменной

// отключение контроля ошибок ввода-вывода

Reset(f); // открытие файла для чтения

// включение контроля ошибок ввода-вывода

ifIOResult<>0 then // если есть ошибка открытия, то

ShowMessage('Ошибка открытия файла C:\1.TXT');

Exit; // выход из процедуры при ошибке открытия файла

While not EOF(f) do // пока не конец файла делать цикл:

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

ShowMessage(st); // выводить строку пользователю

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

Прокомментирую некоторые строки этого примера.

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

и являются директивами компилятору, что в этом месту соответственно следует отключить и включить контроль ошибок ввода-вывода. В данном случае при неудачной попытке открытия файла c:\1.txt (файл отсутствует или открыт для записи другой программой) наша программа не выдаст аварийной ошибки и продолжит выполнение данной процедуры. Это свойство полезно для обработки всех возможных случаев в работе программы.

Работа с текстовыми файлами. Запись в текстовый файл

procedure TForm1.Button1Click(Sender: TObject);

Var f:TextFile; // указатель на текстовый файл

AssignFile(f,'c:\1.txt'); // привязка названия к переменной

Append(f); // открыть файл для добавления

if IOResult<>0 then // если ошибка открытия (напр. файла нет)

Rewrite(f); // создать новый файл

if IOResult<>0 then // ошибка создания файла

ShowMessage('Ошибка создания файла C:\1.TXT');

WriteLn(f,'Привет'); // запись в файл строки с символами перевода строки

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

Процедура Append(Файл) открывает файл для записи и устанавливает указатель записи в конец файла, т.е. все добавляемые к файлу строки будут записаны в конец файла.

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

Запись и чтение из файла не текстовых данных

Рассмотрим пример, в котором программа при выходе сохраняет свои размеры и положение окна на экране в файл и при последующем запуске восстанавливает состояние, которое было при выходе. Программа состоит из двух процедур OnShow и OnClose для окна Form1 программы.

procedure TForm1.FormShow(Sender: TObject);

Var f:file of Integer; // файловая переменная, тип integer

i:Integer; // целочистенная переменная

begin

if IOResult<>0 then Exit;

Read(f,i); //считать из файла значение

Form1.Top:=i; // верхнее положение окна

Form1.Left:=i; // левое положение окна

Form1.Width:=i; // ширина окна

Form1.Height:=i; // высота окна

end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);

Var f:file of Integer;

Читайте также: