Reputation: 1945
I'm trying to convert an old Delphi
app into C#
. It does some stuff with binary files
written via packed records
which I've put below. However, only the BInfoRec
record
is guaranteed to be in the file and appearing first. The others may or may not be in there, and the order of them is unknown. I'm having trouble with one method in particular. It's getting the number of bytes being read in via FileStream.Read
and reading those into one of the packed records
. Then, in the first if
statement (in the delphi version), it is allocating memory on the heap, and doing the same thing as before, but reading it into a pointer. I'm trying to figure out the best way to go about this but I'm by no means an expert with Delphi.
Delphi code:
StartP = packed record
x:SmallInt;
y:SmallInt;
end;
InfoP = packed record
Ycoord:double;
Xcoord:double;
//other vars here
end;
HeadP = packed record
NumP:DWORD;
SizeStruct:DWORD;
SizePoStruct:DWORD;
//other vars here
end;
BInfoRec = packed record
StructNum : WORD ;
in_size : WORD ;
//other variables here
end;
var
tStream:TFileStream;
bInfo:BInfoRec;
RestOfBFile:Pointer;
sizeofRest:Integer;
Function LoadBFile(FileName:String):Boolean;
var
sizeread:Integer;
begin
Try
LoadBFile:=False;
tStream:=TFileStream.Create(Filename,fmOpenRead );
sizeofRest:=tStream.Size-Sizeof(bInfo);
sizeread:=tStream.Read(bInfo,Sizeof(bInfo));
if sizeread = Sizeof(bInfo) then
begin //best way to convert this?
RestOfBFile:=AllocMem(sizeofRest);
sizeread:=tStream.Read(RestOfBFile^,sizeofRest);
if SizeofRest= SizeRead then
LoadBFile:=True;
end;
tStream.Free;
except
LoadBFile:=False;
tStream.Free;
end;
end;
C# (what I have so far):
[Serializable()]
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public struct StartP
{
public short x;
public short y;
}
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public struct InfoP
{
public double Ycoord;
public double Xcoord;
//other vars here
}
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public struct HeadP
{
public UInt32 NumP;
public UInt32 SizeStruct;
public UInt32 SizePoStruct;
//other vars here
}
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public struct BInfoRec
{
public ushort StructNum;
public ushort in_size;
}
BInfoRec bInfo;
int sizeOfRest;
private Boolean LoadBFile(string fileName)
{
int sizeRead;
byte[] buffer = new byte[Marshal.SizeOf(bInfo)];
try
{
using (var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None))
{
sizeOfRest = (int)stream.Length - Marshal.SizeOf(typeof(BInfoRec));
sizeRead = stream.Read(buffer, 0, Marshal.SizeOf(typeof(BInfoRec)));
if (sizeRead == Marshal.SizeOf(typeof(BInfoRec)))
{
//what goes here??
if (sizeOfRest == sizeRead)
{
return true;
}
}
}
}
catch (Exception ex)
{
return false;
}
}
I was thinking about creating a new byte array of unknown size and using a BinaryReader
to read in the rest of the file to that array, then just checking the size of that. Not sure if it's the best way though?
Upvotes: 2
Views: 561
Reputation: 612993
It's a block of memory of arbitrary size. I don't see that you have many options other than a byte array. Yes you could allocate unmanaged memory (e.g. with Marshal.AllocHGlobal
) but that would hardly be convenient.
So, yes, if I were you I would allocate a byte array, and read the contents into it.
Upvotes: 1