gpt4 book ai didi

c# - 将二进制文件读入struct但得到全0?

转载 作者:行者123 更新时间:2023-12-03 19:50:23 25 4
gpt4 key购买 nike

我正在将delphi程序转换为c#,并且必须将二进制文件中的数据读取到struct中。在上一个我在这里提出的问题中,回答了一种方法:Proper struct layout from delphi packed record

但是,当尝试使用我拥有的另一个结构来复制它时,这很好,尽管实际上文件中有数据,但所有数据均为0。该文件是根据这些结构(或delphi版本中的打包记录)进行设置和编写的,并且此特定代码应迭代到文件中的最后一个“结构”,然后将其读入。将同时列出delphi和C#代码。

德尔福:

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个字节。另外,我可以验证 RampStream.Position等于 RampStream.Lengthwhile loop末尾。

最佳答案

Delphi代码的缩进似乎让您感到困惑。应该像这样缩进:

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;


因此,仅当 LastPosition条件为false时才分配 if。当 LastPosition条件为true时,您的C#代码将分配 if。要使C#代码匹配,您可以编写:

while (RampStream.Position < RampStream.Length)
{
RRampRec = ReadRecFromStream2(RampStream);
if ((RRampRec.ShLat == 0) && (RRampRec.ShLong == 0)
&& (RRampRec.FiLat == 0) && (RRampRec.FiLon == 0))
continue;
LastPosition = RRampRec.now;
}


如果是我,我会避免使用 continue并写成这样:

while (RampStream.Position < RampStream.Length)
{
RRampRec = ReadRecFromStream2(RampStream);
if ((RRampRec.ShLat != 0) || (RRampRec.ShLong != 0)
|| (RRampRec.FiLat != 0) || (RRampRec.FiLon != 0))
LastPosition = RRampRec.now;
}


而且我总是对单个/复合语句感到不安,因此我可能会添加大括号:

while (RampStream.Position < RampStream.Length)
{
RRampRec = ReadRecFromStream2(RampStream);
if ((RRampRec.ShLat != 0) || (RRampRec.ShLong != 0)
|| (RRampRec.FiLat != 0) || (RRampRec.FiLon != 0))
{
LastPosition = RRampRec.now;
}
}

关于c# - 将二进制文件读入struct但得到全0?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35873205/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com