How to properly work with FileRead, FileWrite, buffers (or with TFileStream).
I need to read a whole text file to a String, then to write back a String to this file
Added requested example of working with FileXXX function family too.
Note on using RawByteString and file I/O - it is perfectly valid.
Another note: for brevity in the low-level code i omitted some error-checking assertions for less likely occurring errors. Caveat emptor!
const
FileName = 'Unit14.pas'; // this program is a stuntmaster,
// reads and writes its own source
procedure TForm14.FormClick(Sender: TObject);
var
Stream: TFileStream;
Buffer: RawByteString;
begin
Stream := TFileStream.Create(FileName, fmOpenReadWrite or fmShareExclusive);
// read entire file into string buffer
SetLength(Buffer, Stream.Size);
Stream.ReadBuffer(Buffer[1], Stream.Size);
// do something with string
OutputDebugString(PChar(Format('Buffer = "%s"', [Buffer])));
// prepare to write
Stream.Position := 0; // rewind file pointer
Stream.Size := 0; // truncate the file
// write entire string into the file
Stream.WriteBuffer(Buffer[1], Length(Buffer));
Stream.Free;
end;
// on right click - do exactly the same but using low-level FileXXX calls
procedure TForm14.FormContextPopup(Sender: TObject; MousePos: TPoint; var
Handled: Boolean);
var
Handle: Integer;
Size: Cardinal;
Buffer: RawByteString;
Transferred: Integer;
begin
Handle := FileOpen(FileName, fmOpenReadWrite or fmShareExclusive);
Assert(Handle >= 0);
// read entire file into string buffer
Size := GetFileSize(Handle, nil);
Assert(Size <> INVALID_FILE_SIZE);
SetLength(Buffer, Size);
Transferred := FileRead(Handle, Buffer[1], Size);
Assert(not (Transferred < Size));
// do something with string
OutputDebugString(PChar(Format('Buffer = "%s"', [Buffer])));
// prepare to write
FileSeek(Handle, 0, 0); // rewind file pointer
SetEndOfFile(Handle); // truncate the file
// write entire string into the file
Transferred := FileWrite(Handle, Buffer[1], Length(Buffer));
Assert(not (Transferred < Length(Buffer)));
FileClose(Handle);
end;