I want to open a 50 MB binary and read only the last 4 bytes and convert it to a string for some purpose.
The only way I found this now is to use LoadStringFromFile to completely load the file in memory and then copy the last 4 bytes, however this method is very slow because the binary is heavy.
Is there a better way to do this in an Inno Setup script?
Update:
This is the final working function that I edited from Martin Prikril.
function readlast4byte() : AnsiString; var Stream: TFileStream; Buffer: string; Count: Integer; Index: Integer; begin Count := 4; Stream := TFileStream.Create('C:\test.txt', fmOpenRead); try Stream.Seek(-Count, soFromEnd); SetLength(Buffer, 1); SetLength(Result, Count); for Index := 1 to Count do begin Stream.ReadBuffer(Buffer, 1); Result[Index] := Chr(Ord(Buffer[1])) ; end; finally Stream.Free; end; end;
Update 2:
Also, this is another great work written by TLama and should also be noted as an answer:
[Code] #IFNDEF Unicode #DEFINE CharSize 1 #ELSE #DEFINE CharSize 2 #ENDIF type TSeekOrigin = ( soBeginning, soCurrent, soEnd ); #IFDEF UNICODE function BufferToAnsi(const Buffer: string): AnsiString; var W: Word; I: Integer; begin SetLength(Result, Length(Buffer) * 2); for I := 1 to Length(Buffer) do begin W := Ord(Buffer[I]); Result[(I * 2)] := Chr(W shr 8); // high byte Result[(I * 2) - 1] := Chr(Byte(W)); // low byte end; end; #ENDIF function ReadStringFromFile(const FileName: string; Origin: TSeekOrigin; Offset, Length: Integer; var S: AnsiString): Boolean; var Buffer: string; Stream: TFileStream; begin Result := True; try Stream := TFileStream.Create(FileName, fmOpenRead); try Stream.Seek(Offset, Ord(Origin)); SetLength(Buffer, Length div {#CharSize}); Stream.ReadBuffer(Buffer, Length); #IFNDEF UNICODE S := Buffer; #ELSE S := BufferToAnsi(Buffer); #ENDIF finally Stream.Free; end; except Result := False; end; end;
inno-setup pascalscript
DucFabulous Jul 05 '15 at 7:28 2015-07-05 07:28
source share