William23668 8 Posted December 24, 2021 Hi I was able to read the file byte by byte but the app hangup/not responding I dont know why ? Here is the code: var AFile: TFileStream; BR: TBinaryReader; MyByteArray: TBytes; mstr: String; i: integer; begin AFile := TFileStream.Create(filename, fmOpenRead); BR := TBinaryReader.Create(AFile, TEncoding.Unicode, false); try SetLength(MyByteArray, AFile.Size); // Get the whole file contents into the byte array MyByteArray := BR.ReadBytes(AFile.Size); for i := low(MyByteArray) to High(MyByteArray) do begin SetString(mstr, PAnsiChar(@MyByteArray[i]), Length(MyByteArray)); RichEdit1.Text := RichEdit1.Text + mstr; end; BR.Close; finally BR.Free; AFile.Free; end; end; Share this post Link to post
Remy Lebeau 1394 Posted December 24, 2021 (edited) I see several issues with that code: 1. your SetLength() is useless, because the subsequent ReadBytes() is completely replacing your allocated array with a different array allocates by ReadBytes(). 2. your SetString() is wrong, for two reasons: a. String is UnicodeString in D2009+, which you are clearly using due to TEncoding, which was also introduced in D2009. You are trying to populate the UnicodeString with AnsiChar data, but there is no overload of SetString() for that. You can only populate a UnicodeString with WideChar data. For AnsiChar data, you need to use AnsiString instead. b. You are advancing a PAnsiChar pointer through the byte array, but you are giving the array's whole length to SetString(), which means SetString() is going to read beyond the end of the array into surrounding memory after the 1st loop iteration. Since you are trying to convert each Byte into an (Ansi)String, you would need to use 1 for the SetString() length instead. 3. appending strings to the RichEdit1.Text property in a loop is VERY inefficient. It requires reading the RichEdit's entire content into a String in memory, then expanding that String in memory with appended data, then replacing the RichEdit's entire content with the new string. A much more efficient way to append strings to a RichEdit's content is to use its SelText property instead, eg: RichEdit1.SelStart := RichEdit1.GetTextLen; RichEdit1.SelLength := 0; RichEdit1.SelText := ...; But even that is not the best approach in this situation. Since you are trying to display a byte array as-is in the RichEdit as text, you may as well just assign the RichEdit.Text property 1 time with the entire array as 1 string, no loop needed at all, eg: var AFile: TFileStream; BR: TBinaryReader; MyByteArray: TBytes; mstr: AnsiString; begin AFile := TFileStream.Create(filename, fmOpenRead); BR := TBinaryReader.Create(AFile, TEncoding.Unicode, false); try // Get the whole file contents into the byte array MyByteArray := BR.ReadBytes(AFile.Size); SetString(mstr, PAnsiChar(@MyByteArray[0]), Length(MyByteArray)); RichEdit1.Text := mstr; // or: RichEdit1.Text := TEncoding.ANSI.GetString(MyByteArray); BR.Close; finally BR.Free; AFile.Free; end; end; In which case, you may as well just get rid of the TBinaryReader, as you can read bytes from the TFileStream directly: var AFile: TFileStream; MyByteArray: TBytes; mstr: AnsiString; begin AFile := TFileStream.Create(filename, fmOpenRead); try SetLength(MyByteArray, AFile.Size); // Get the whole file contents into the byte array AFile.ReadBuffer(MyByteArray[0], SetLength(MyByteArray)); SetString(mstr, PAnsiChar(@MyByteArray[0]), Length(MyByteArray)); RichEdit1.Text := mstr; // or: RichEdit1.Text := TEncoding.ANSI.GetString(MyByteArray); finally AFile.Free; end; end; In which case, you can just get rid of the TFileStream altogether, too: RichEdit1.Text := TFile.ReadAllText(filename, TEncoding.ANSI); Or RichEdit1.Lines.LoadFromFile(filename, TEncoding.ANSI); Edited December 24, 2021 by Remy Lebeau 1 Share this post Link to post
William23668 8 Posted December 24, 2021 (edited) @Remy Lebeau Many thanks I learned many things now. I just need to read byte by byte for processing later. Edited December 24, 2021 by William23668 Share this post Link to post
David Heffernan 2345 Posted December 24, 2021 You aren't going to be able to display the contents of a binary file in a rich edit control like this. If you want a hex editor, then display each byte as hex. 1 Share this post Link to post
William23668 8 Posted December 24, 2021 11 hours ago, David Heffernan said: You aren't going to be able to display the contents of a binary file in a rich edit control like this. If you want a hex editor, then display each byte as hex. Just for learning why the app stop responding ? if I used richedit LoadFromStream it load fine. Share this post Link to post
David Heffernan 2345 Posted December 24, 2021 8 hours ago, William23668 said: Just for learning why the app stop responding ? if I used richedit LoadFromStream it load fine. But it's not text, you can't treat it as text, and there's nothing to learn. What you should learn is how text is encoded. Why not do that? 1 Share this post Link to post