My win32 program created a binary file with only a string[32] and an integer right after it. Then, I wrote a .NET program to read that same file.
Here is my .NET code:
method ReadUnitFile;
var
FHeader:TFileHeader;
Biread:BinaryReader;
FUnitLoc:String;
begin
FUnitLoc := baseDir+'\system\Units.dat';
if Environment.OSVersion.Platform = System.PlatformID.Unix then
FUnitLoc := baseDir+'/system/Units.dat';
if File.Exists(FUnitLoc) then
begin
Biread:= new BinaryReader(File.OpenRead(FUnitLoc));
FHeader.id:=Biread.ReadString;
FHeader.version:=Biread.ReadInt32;
Biread.Close;
end;
end;
It failed to read the file probably. In fact, it raised "read beyond end of file" exception. The reason for that is because the string is exactly 32 characters long. I believe that the BinaryReader doesn't have the information. So, it reads beyond 32 characters for the string. Thus, it fails to read the binary file properly.
So, how do you read a binary-win32-file under .NET framework in this case?
UPDATE
Here is my .NET updated code:
method ReadUnitFile;
var
FHeader:TFileHeader;
Biread:BinaryReader;
FUnitLoc:String;
tmparray:array[0..32] of char;
begin
FUnitLoc := baseDir+'\system\Units.dat';
if Environment.OSVersion.Platform = System.PlatformID.Unix then
FUnitLoc := baseDir+'/system/Units.dat';
if File.Exists(FUnitLoc) then
begin
Biread:= new BinaryReader(File.OpenRead(FUnitLoc));
Biread.Read(tmparray,0,32);
FHeader.id := tmparray.ToString;
FHeader.version:=Biread.ReadInt32;
Biread.Close;
end;
end;
Although this works, I can't seem to retrieve the string from tmparray. FHeader.id is a string type. ToString doesn't seem to be working right. After that line of code, FHeader.id is equals "System.Char[]." It doesn't actually contain the string itself.
Any idea?
Thanks in advance,
You stored a Delphi ShortString
into the file. A ShortString
contains a Byte
at the beginning to specify how many AnsiChar
elements are in the ShortString
. In your .NET code, you need to read a Byte
, then read the specified number of 8-bit characters, then read a 4-byte integer, eg:
method ReadUnitFile;
var
FHeader: TFileHeader;
Biread: BinaryReader;
FUnitLoc: String;
begin
FUnitLoc := baseDir+'\system\Units.dat';
if Environment.OSVersion.Platform = System.PlatformID.Unix then
FUnitLoc := baseDir+'/system/Units.dat';
if File.Exists(FUnitLoc) then
begin
Biread := new BinaryReader(File.OpenRead(FUnitLoc));
FHeader.id := System.Encoding.Default.GetString(Biread.ReadBytes(Biread.ReadByte));
FHeader.version := Biread.ReadInt32;
Biread.Close;
end;
end;