zig
zig

Reputation: 4624

What is the TFileStream equivalent to pascal IO Append(F)?

I assume it is:

FS := TFileStream.Create(FileName, fmOpenReadWrite);
FS.Seek(0, soFromEnd); 

Is that correct? is the open mode correct or maybe fmOpenWrite or need to add fmShareDenyNone?

PS: For Rewrite(F) I used FS := TFileStream.Create(FileName, fmCreate);


Based on @David's comments I ended up using THandleStream

procedure LOG(const FileName: string; S: string);
const
  FILE_APPEND_DATA = 4;
  OPEN_ALWAYS = 4;
var
  Handle: THandle;
  Stream: THandleStream;
begin
  Handle := CreateFile(PChar(FileName),
    FILE_APPEND_DATA, // Append data to the end of file
    0, nil,
    OPEN_ALWAYS, // If the specified file exists, the function succeeds and the last-error code is set to ERROR_ALREADY_EXISTS (183).
                 // If the specified file does not exist and is a valid path to a writable location, the function creates a file and the last-error code is set to zero.
    FILE_ATTRIBUTE_NORMAL, 0);

  if Handle <> INVALID_HANDLE_VALUE then
  try
    Stream := THandleStream.Create(Handle);
    try
      S := S + #13#10;
      Stream.WriteBuffer(S[1], Length(S) * SizeOf(Char));
    finally
      Stream.Free;
    end;
  finally
    FileClose(Handle);
  end
  else
    RaiseLastOSError;
end;

Upvotes: 2

Views: 1699

Answers (2)

RBA
RBA

Reputation: 12584

It should be like this

var
  FileName: string;
  FS: TFileStream;
  sOut: string;
  i: Integer;
  Flags: Word;
begin
  FileName := ...; // get your file name from somewhere
  Flags := fmOpenReadWrite;
  if not FileExists(FileName) then
    Flags := Flags or fmCreate;
  FS := TFileStream.Create(FileName, 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;

This code also verify if the file doesn't exist, and if not then creates the file.

Concerning the flags, you can find a definition for each one of them in the documentation

Upvotes: 3

Uwe Raabe
Uwe Raabe

Reputation: 47694

Actually it would be

FStream := TFileStream.Create(Filename, fmOpenWrite);
FStream.Seek(0, soEnd);

You can see an example in TBinaryWriter.Create or TStreamWriter.Create - or you just opt to use one of these classes directly.

Upvotes: 6

Related Questions