web-dev-qa-db-ja.com

ファイルの作成および/または書き込み

これは簡単だと思うが、現時点ではグーグルは完全に失敗している。ファイルを開くか、存在しない場合は作成して、書き込みたいです。

以下

AssignFile(logFile, 'Test.txt');
Append(logFile);

ファイルがまだ存在しない場合、2行目にエラーがスローされます。しかし、a)ファイルが存在するかどうかをテストし、b)必要なときにファイルを作成する方法を見つけることに本当に失敗しています。

参考までに、Delphi XEで作業しています。

21
Eric G

FileExists 関数を使用してから Append が存在する場合、または Rewrite を使用できます。そうでない場合。

    AssignFile(logFile, 'Test.txt');

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

   //do your stuff

    CloseFile(logFile); 
36
RRUZ

FileExistsを使用してファイルを開く方法を選択するソリューションには、競合状態があります。ファイルをテストしてからファイルを開こうとするまでの間にファイルの存在が変わると、プログラムは失敗します。 Delphiは、ネイティブファイルI/Oルーチンでその問題を解決する方法を提供していません。

ご使用のDelphiバージョンが十分に新しい場合、 TFile.OpenfmOpenOrCreateオープンモードで使用できます。 TFileStreamを返します。

それ以外の場合は、代わりにWindows API関数CreateFileを使用してファイルを開くことができます。 dwCreationDispositionパラメーターをOPEN_ALWAYSに設定します。これは、ファイルが存在しない場合は作成するように指示します。

24
Rob Kennedy

代わりに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;
10
Ken White

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;
5

単純なことをしているだけなら、IOUtilsユニットの方がずっと簡単です。ファイルに書き込むためのユーティリティがたくさんあります。

例えば.

プロシージャWriteAllText(constパス:文字列; const内容:文字列);過負荷;静的;

新しいファイルを作成し、指定された文字列をファイルに書き込み、ファイルを閉じます。ターゲットファイルが既に存在する場合、上書きされます。

4
awmross