I want to read a binary file and display the result in a memo but not how to do with this error: "Incompatible types: 'string' and 'Array'", the code is this
unit yo;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
F: TFileStream;
Buffer: array [0 .. 1023] of byte;
begin
F := TFileStream.Create(ExtractFilePath(Application.ExeName)
+ 'yo.exe', fmOpenRead);
while F.Position < F.Size do
begin
F.Read(Buffer, 1024);
Memo1.Lines.Add(Buffer);
end;
F.Free;
end;
managed to avoid this error and to run the program without errors ?
anyone can help me?
You can't directly bypass this error, because a string and an array[] of Byte are not directly assignable.
Since binary content (the #0 character in particular, or the 0x00 hex value (C/C++)) won't be displayable in a TMemo anyway (the text would be terminated at the first #0 value), you'd need to replace it with something.
The easiest way to get past the compiler error is to change your array from array[] of Byte to array[] of AnsiChar, which can be directly assigned to a string (or typecast to one):
var
Buffer: array[0..1023] of AnsiChar;
TempStr: string;
begin
// Fill buffer from stream
TempStr := Buffer;
Memo1.Lines.Add(TempStr);
// The next line eliminates the need for `TempStr`
// Memo1.Lines.Add(String(Buffer));
end;
However, like I said, this won't solve the problem of displaying in the memo. For instance, when actually reading a Windows executable, the first buffer displays MZP, because the fourth byte is a #0 and the memo terminates the string.
To overcome this limitation, you need to replace all #0 characters with something else. The problem with that, of course, is that any value you replace it with can also actually occur in the executable (since they're bytes, there are only 256 possible values). Again, the simple solution is to replace all #0 characters with 0 (#216):
var
Buffer: array[0..1023] of AnsiChar;
i: Integer;
TempStr: string;
begin
// Fill buffer as before
for i := Low(Buffer) to High(Buffer) do
if Buffer[i] = #0 then
Buffer[i] := `Ø`; // Try #144 instead
TempStr := Buffer;
Memo1.Lines.Add(TempStr);
// You can still eliminate the string variable by typecasting
// Memo1.Lines.Add(String(TempStr));
end;
Here's code for a TForm.FormCreate event that actually reads a 1K buffer from a Delphi console application, does the above replacement, and displays the content in a TMemo. Drop the TMemo on a form, set its Alignment property to alClient, and ScrollBars to ssVertical. Add a FormCreate event handler to the form, and use the following code for that event:
procedure TForm1.FormCreate(Sender: TObject);
var
Stream: TFileStream;
Buffer: array[0..1023] of AnsiChar;
TempStr: string;
i: Integer;
begin
Memo1.Clear;
// Populate buffer elements
Stream := TFileStream.Create('D:\Temp\Project2.exe', fmOpenRead);
try
Stream.Read(Buffer[0], SizeOf(Buffer));
finally
Stream.Free;
end;
// Replace null (#0) values with #216 (Ø)
for i := Low(Buffer) to High(Buffer) do
if Buffer[i] = #0 then
Buffer[i] := 'Ø';
TempStr := Buffer;
Memo1.Lines.Add(TempStr);
end;
NOTE: If you're actually reading the entire binary file instead of just the first buffer, the last buffer might not be entirely full of the file content (you might not read a full buffer on the last pass). In that case, you want to mark the end of the buffer with a #0 so that the memo correctly displays that partial buffer. You can change the for loop to use something like this:
for i := Low(Buffer) to High(Buffer) do
begin
if (i = BytesRead) then
begin
Buffer[i] := #0; // Mark the end of the buffer and exit loop;
Break;
end
else if (Buffer[i] = #0) then
Buffer[i] := 'Ø';
end;
Here's the output of reading a single buffer full:

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With