我正在將delphi
程序轉換爲c#
,我必須將數據從二進制文件讀取到struct
。一個方法來解決這個問題,我在這裏問了一個前面的問題:Proper struct layout from delphi packed record。讀取二進制文件到結構,但獲得全0?
但是,當試圖用另一個結構體來複制這個結構時,這很有效,所有數據都是0,儘管文件中實際上有數據。該文件的設置是根據這些結構(或delphi版本中的打包記錄)編寫的,並且此特定代碼應該迭代到文件中的最後一個「結構」並讀入。將列出delphi和c#代碼。
的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();
}
}
注意:在流已經在位置128從在先前的結構,該文件的第一個結構讀取。所以RampStream.Position = 128
開始這些功能時。
任何想法在這裏可能會出錯?我可以一次確認流的位置正確地上升128個字節。另外,我可以在while loop
的末尾驗證RampStream.Position
等於RampStream.Length
。
嘗試調試器。檢查來自文件的內容。 –
它似乎是最後一個背後的'記錄'。現在看起來這很有意義,'while循環'只在位置是時才執行,但需要'=='然後分配內容。我很好奇爲什麼'Delphi'' while循環工作。它包含文件中的最後一條記錄(最後128個字節)。 –
pfinferno