Search code examples
delphidelphi-xe7delphi-xe4

TFileStream.WriteBuffer XE4 VS XE7


This code is running on Delphi XE4 perfectly well:

var
b: byte;
fl: TFileStream;
filename:string;
begin
b:= $2F;
filename:='C:\test.exe';
fl:= tFileStream.Create(filename, 0,fmOpenReadWrite);
fl.Position:= $C;
fl.WriteBuffer(b,sizeof(b));
fl.free
end;

However, when I run exactly the same code on Delphi XE7 on the same PC, it fails with the error "Stream write error".


Solution

  • In the TFileStream constructor, you are setting the Mode parameter to 0 (fmOpenRead) and the Rights parameter to fmOpenReadWrite. You need to swap them:

    //fl:= tFileStream.Create(filename, 0, fmOpenReadWrite);
    fl:= tFileStream.Create(filename, fmOpenReadWrite, 0);
    

    Or simply:

    fl:= tFileStream.Create(filename, fmOpenReadWrite);
    

    When the fmCreate flag is not present in the Mode parameter, TFileStream calls FileOpen() instead of FileCreate().

    In XE4, the Mode and Rights parameters are OR'ed together when TFileStream calls FileOpen() on Windows:

    inherited Create(FileOpen(AFileName, Mode or Rights));
    // which is: FileOpen(AFileName, fmOpenRead or fmOpenReadWrite)
    // effectively: FileOpen(AFileName, fmOpenReadWrite)
    

    That is why your code works in XE4. You are opening the file in a read/write mode.

    In XE7, the Rights parameter is ignored when TFileStream calls FileOpen() on every platform:

    inherited Create(FileOpen(AFileName, Mode));
    // effectively: FileOpen(AFileName, fmOpenRead)
    

    That is why your code does not work in XE7. You are opening the file in a read-only mode.