Создание и/или запись в файл
Я чувствую, что это должно быть легко, но Google сейчас полностью не работает. Я хочу открыть файл или создать его, если он не существует, и написать ему.
Следующие
AssignFile(logFile, 'Test.txt');
Append(logFile);
выдает ошибку во второй строке, когда файл еще не существует, что, как я предполагаю, ожидается. Но я действительно не в состоянии выяснить, как: a) проверить, существует ли файл, и b) создать его при необходимости.
FYI, работающий в Delphi XE.
Ответы
Ответ 1
Вы можете использовать функцию FileExists
, а затем использовать Append
, если существует, или Rewrite
, если нет.
AssignFile(logFile, 'Test.txt');
if FileExists('test.txt') then
Append(logFile)
else
Rewrite(logFile);
//do your stuff
CloseFile(logFile);
Ответ 2
Любое решение, использующее FileExists
для выбора способа открытия файла, имеет условие гонки. Если существование файла изменяется между временем его тестирования и временем, когда вы пытаетесь открыть файл, ваша программа завершится с ошибкой. Delphi не предоставляет какой-либо возможности для решения этой проблемы с помощью собственных подпрограмм ввода-вывода файлов.
Если ваша версия Delphi достаточно новая, чтобы предложить ее, вы можете использовать TFile.Open
с открытым режимом fmOpenOrCreate
, что делает именно то, что вы хотите; он возвращает a TFileStream
.
В противном случае вы можете использовать функцию Windows API CreateFile
, чтобы открыть файл. Установите для параметра dwCreationDisposition
значение OPEN_ALWAYS
, в котором говорится, что он создает файл, если он еще не существует.
Ответ 3
Вместо этого вы должны использовать TFileStream
. Здесь образец, который создаст файл, если он не существует, или напишите ему, если он делает:
var
FS: TFileStream;
sOut: string;
i: Integer;
Flags: Word;
begin
Flags := fmOpenReadWrite;
if not FileExists('D:\Temp\Junkfile.txt') then
Flags := Flags or fmCreate;
FS := TFileStream.Create('D:\Temp\Junkfile.txt', Flags);
try
FS.Position := FS.Size; // Will be 0 if file created, end of text if not
sOut := 'This is test line %d'#13#10;
for i := 1 to 10 do
begin
sOut := Format(sOut, [i]);
FS.Write(sOut[1], Length(sOut) * SizeOf(Char));
end;
finally
FS.Free;
end;
end;
Ответ 4
Если вы просто делаете что-то простое, модуль IOUtils намного проще. Он имеет множество утилит для записи в файлы.
например.
procedure WriteAllText (const Path: string; const Содержимое: строка); перегрузки; статические;
Создает новый файл, записывает указанную строку в файл, а затем закрывает файл. Если целевой файл уже существует, он перезаписывается.
Ответ 5
Вы также можете использовать функцию загрузки/сохранения в TStringList
, чтобы решить вашу проблему.
Это может быть плохое решение, потому что весь файл будет загружен в память, изменен в памяти и затем сохранен для возврата на диск. (В отличие от вашего решения, где вы просто пишете непосредственно в файл). Это явно плохое решение для многопользовательских ситуаций.
Но этот подход подходит для небольших файлов, и с ним легко работать и легко понять.
const
FileName = 'test.txt';
var
strList: TStringList;
begin
strList := TStringList.Create;
try
if FileExists(FileName) then
strList.LoadFromFile(FileName);
strList.Add('My new line');
strList.SaveToFile(FileName);
finally
strList.Free;
end;
end;