创建和/或写入文件

Eri*_*c G 21 delphi delphi-xe

我觉得这应该很容易,但谷歌目前完全失败了.我想打开一个文件,或者如果它不存在就创建它,并写入它.

下列

AssignFile(logFile, 'Test.txt');
Append(logFile);
Run Code Online (Sandbox Code Playgroud)

当文件不存在时,在第二行引发错误,我认为这是预期的.但我真的没有找到如何a)测试文件是否存在和b)在需要时创建它.

仅供参考,在Delphi XE工作.

RRU*_*RUZ 36

您可以使用该FileExists功能,然后使用(Append如果存在)或Rewrite不使用.

    AssignFile(logFile, 'Test.txt');

    if FileExists('test.txt') then
      Append(logFile)
    else
      Rewrite(logFile);

   //do your stuff

    CloseFile(logFile); 
Run Code Online (Sandbox Code Playgroud)

  • 您可以使用 System.IOUtils.TFile.AppendAllText( 'test.txt',contents );` 使其更加简洁和可读 - 另请参阅[awmross的答案](/sf/answers/548214201/ 2822719)。它保证完全按照您想要的方式进行:“_如果 Path 参数指定的文件存在,则将文本附加到其中;否则,将创建文件并填充给定的文本。_”——来自 [官方文档] ](http://docwiki.embarcadero.com/Libraries/Rio/en/System.IOUtils.TFile.AppendAllText) (3认同)

Rob*_*edy 24

FileExists用于选择如何打开文件的任何解决方案都存在竞争条件.如果文件的存在在您测试它和尝试打开文件的时间之间发生变化,则程序将失败.Delphi没有提供任何方法来解决其本机文件I/O例程的问题.

如果你的Delphi版本够新,提供它,您可以使用TFile.OpenfmOpenOrCreate开放的模式,这不正是你想要的东西; 它返回一个TFileStream.

否则,您可以使用Windows API函数CreateFile来打开文件.将dwCreationDisposition参数设置为OPEN_ALWAYS,告诉它创建文件(如果该文件尚不存在).

  • TFile.Open依赖于FileExist,因此它不能解决竞争条件 (5认同)

Ken*_*ite 10

你应该使用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;
Run Code Online (Sandbox Code Playgroud)

  • @DavidHeffernan肯答案建议如果使用标志`fmOpenReadWrite或fmCreate`,将创建或打开文件以追加数据.(检查行`FS.Position:= FS.Size;`)但是会发生这种情况,因为如果存在标志`fmCreate`,则总是重新创建文件. (3认同)
  • @Eric您首选的方法不执行Unicode并且被高度弃用. (2认同)

awm*_*oss 5

如果您只是在做一些简单的事情,那么 IOUtils 单元要容易得多。它有很多用于写入文件的实用程序。

例如

过程WriteAllText(常量路径:字符串;常量内容:字符串);超载; 静止的;

创建一个新文件,将指定的字符串写入文件,然后关闭文件。如果目标文件已经存在,它会被覆盖。

  • 该问题特别说明“如果它不存在则创建”,并使用`Append`,所以我怀疑如果它已经存在,他们想要追加。您的引用说“如果目标文件已存在,则将其覆盖”,因此阻止附加。:) 没有downvote - 只是说'.... (3认同)

Jør*_*eit 5

您还可以使用a中的加载/保存功能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;
Run Code Online (Sandbox Code Playgroud)