Mr. Daniel 0 Posted September 22, 2020 Dear all, I am experiencing a strange error which I have narrowed down to a small piece of code (see below). I am reading a binary file into a TMemoryStream (variable ms1), through a TFileStream object (variable fs). Then I want to copy the binary data to another TMemoryStream object (ms2). This is what gives me the "stream read error" exception. Strange thing is, that if I don't load up the ms1 object with the file contents, things work fine, i.e. ms2.CopyFrom does not give me an exception.. Any help is greatly appreciated.... procedure TForm5.BitBtn1Click(Sender: TObject); var ms1: TMemoryStream; fs: TFileStream; ms2 : TMemoryStream; FilePath: string; begin FilePath := 'C:\weekcpdf_tech6.bin'; ms1 := TMemoryStream.Create; fs := nil; try ms1 := TMemoryStream.Create; fs := TFileStream.Create(FilePath, fmOpenRead); ms1.CopyFrom(fs, fs.Size); ms2 := TMemoryStream.Create; ms2.CopyFrom(ms1, ms1.Size); finally FreeAndNil(fs); FreeAndNil(ms1); end; end; Share this post Link to post
Rollo62 536 Posted September 22, 2020 (edited) procedure TForm5.BitBtn1Click(Sender: TObject); var ms1: TMemoryStream; fs: TFileStream; ms2 : TMemoryStream; FilePath: string; begin FilePath := 'C:\weekcpdf_tech6.bin'; ms1 := nil; //TMemoryStream.Create; //<== double Create ms2 := nil; //<== missing prepare ms2 fs := nil; try ms1 := TMemoryStream.Create; //<== double Create fs := TFileStream.Create(FilePath, fmOpenRead); //<== I would check if fs valid here fs.Position := 0; //<== I would ensure Position 0 here ms1.CopyFrom(fs, fs.Size); ms1.Position := 0; //<== I would ensure Position 0 here ms2 := TMemoryStream.Create; ms2.CopyFrom(ms1, ms1.Size); //<== I would check if ms1 valid here finally FreeAndNil(fs); FreeAndNil(ms1); FreeAndNil(ms2); //<== missing free end; end; Just some obvious observations from fast overview ... Edited September 22, 2020 by Rollo62 Share this post Link to post
Anders Melander 1782 Posted September 22, 2020 In the calls to LoadFromStream set the Size parameter to 0 (zero). That resets the position to zero and copies everything in the source stream. Share this post Link to post
David Heffernan 2345 Posted September 22, 2020 Why are you cross posting? https://stackoverflow.com/questions/64010603/delphi-getting-stream-read-error-on-really-simple-program At every site where you cross post, potentially different people will provide you the answer. Which means that more people than necessary spend time on this. As a broad rule, people who provide this sort of help don't appreciate this kind of behaviour. 2 Share this post Link to post
Remy Lebeau 1393 Posted September 22, 2020 (edited) 3 hours ago, Mr. Daniel said: I am experiencing a strange error which I have narrowed down to a small piece of code (see below). I am reading a binary file into a TMemoryStream (variable ms1), through a TFileStream object (variable fs). Then I want to copy the binary data to another TMemoryStream object (ms2). This is what gives me the "stream read error" exception. Strange thing is, that if I don't load up the ms1 object with the file contents, things work fine, i.e. ms2.CopyFrom does not give me an exception.. You are not resetting the ms1.Position property back to 0 after calling ms1.CopyFrom(fs, fs.Size) and before calling ms2.CopyFrom(ms1, ms1.Size). After ms1.CopyFrom() is done reading from the TFileStream, ms1.Position is at the end of the stream, it is not reset back to 0 automatically. You are then asking ms2 to read ms1.Size bytes from the end of the ms1 stream, hence the error. Calling TStream.CopyFrom() with its Count parameter set to <= 0 will reset the source TStream.Position to 0 and read all of the source TStream's bytes. But you are not doing that, you are setting the Count parameter to the source TStream.Size instead, so CopyFrom() will read from the source TStream's current Position, and fail if the requested number if bytes is not read successfully. Edited September 22, 2020 by Remy Lebeau Share this post Link to post
Mr. Daniel 0 Posted September 23, 2020 Thanks all, this was very helpful and basic to working with streams. I hadn't thought of the .Position property. Share this post Link to post