I'm converting a delphi
program to c#
and I have to read data from a binary file into a struct
. A way to do this was answered in a previous question I asked here: Proper struct layout from delphi packed record .
That works great, however, when trying to replicate this with another struct I have, all the data is 0, even though there is in fact data in the file. The file is set-up and was written in terms of these structs (or packed records in the delphi version), and this specific code is supposed to iterate to the last 'struct' in the file, and read it in. I'm going to list both the delphi and c# code.
Delphi:
CONST
RecordSize=128;
HeaderSize=128;
Testrec = packed record
now: TDateTime;
ShLat: longint;
ShLong: longint;
ShLatUn: short;
ShLonUn: short;
ShSens1: short;
ShSens2: short;
ShAlt: single;
ShFirst: single;
ShDepth: single;
ShSpeed: single;
ShHead: single;
ShCourse: single;
ShRoll: single;
ShPitch: single;
ShVOS: single;
FiLat: longint;
FiLong: longint;
FiLatUn: short;
FiLonUn: short;
FiSens1: short;
FiSens2: short;
FiAlt: single;
FiFirst: single;
FiDepth: single;
FiSpeed: single;
FiHead: single;
FiCourse: single;
FiRoll: single;
FiPitch: single;
FiVOS: single;
DataFlags: longint;
RevFlags: longint;
Contact: longint;
Range1: short;
Range2: short;
end;
var
RampStream:TFileStream;
Function GetLastTime:TDateTime;
var
RRampRec:TestRec;
LastPosition:TDateTime;
HoldPosition:Int64;
begin
LastPosition:=0;
HoldPosition:= RampStream.Position;
RampStream.Position:=128;
While RampStream.Position < RampStream.Size do
begin
RampStream.Read(RRampRec,RecordSize);
if (RRampRec.ShLat = 0) AND (RRampRec.ShLon = 0) AND
(RRampRec.FiLat = 0) AND (RRampRec.FiLon = 0) then continue;
LastPosition:= RRampRec.Now;
end;
RampStream.Position:=HoldPosition;
GetLastTime:=Lastposition;
end;
C#:
const int RecordSize = 128;
const int HeaderSize = 128;
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Testrec
{
public double now;
public int ShLat;
public int ShLon;
public short ShLat;
public short ShLon;
public short ShSens1;
public short ShSens2;
public float ShAlt;
public float ShFirst;
public float ShDepth;
public float ShSpeed;
public float ShHead;
public float ShCourse;
public float ShRoll;
public float ShPitch;
public float ShVOS;
public int FiLat;
public int FiLon;
public short FhLatUn;
public short FhLonUn;
public short FhSens1;
public short FhSens2;
public float FhAlt;
public float FhFirst;
public float FhDepth;
public float FhSpeed;
public float FhHead;
public float FhCourse;
public float FhRoll;
public float FhPitch;
public float FhVOS;
public int DataFlags;
public int RevFlags;
public int Contact;
public short Range1;
public short Range2;
}
FileStream RampStream;
private Double GetLastTime()
{
Testrec RRampRec = new Testrec();
double LastPosition;
long HoldPosition;
LastPosition = 0;
HoldPosition = RampStream.Position;
RampStream.Position = 128;
while (RampStream.Position < RampStream.Length)
{
RRampRec = ReadRecFromStream2(RampStream);
if ((RRampRec.ShLat == 0) && (RRampRec.ShLong == 0) && (RRampRec.FiLat == 0) && (RRampRec.FiLon == 0))
{
LastPosition = RRampRec.now;
}
}
RampStream.Position = HoldPosition;
return LastPosition;
}
TestrecReadRecFromStream2(Stream stream)
{
byte[] buffer = new byte[Marshal.SizeOf(typeof(Testrec))];
stream.Read(buffer, 0, HeaderSize);
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
try
{
return (Testrec)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(Testrec));
}
finally
{
handle.Free();
}
}
Notes: the stream is already at position 128 from reading in a previous struct, the first struct of the file. So RampStream.Position = 128
when beginning these functions.
Any idea what could be going wrong here? I can verify the position of the stream is correctly going up by 128 bytes at a time. Also, I can verify that RampStream.Position
is equal to RampStream.Length
at the end of the while loop
.