gpt4 book ai didi

c# - 使用 C# 将连续的结构化数据写入二进制文件

转载 作者:行者123 更新时间:2023-11-30 16:54:38 27 4
gpt4 key购买 nike

我正在做一个项目,需要将结构化数据写入二进制文件。首先,我需要编写一个 header ,然后从某处获取数据,填充结构化数据 block 并将其写入所述文件。我将 C 结构移植到 C#,如下所示:

C 头结构:

typedef struct
{
DWORD uSignature;
DWORD uRecordLength;
} Header;

C 数据结构:

typedef struct
{
DWORD uCode; // a two character identifier
char uLabel[10];
int uDate;
float uData[37];
} MyData;

这是 C# header 结构:

    struct Header
{
public uint uSignature;
public uint uRecordLength;
}

这是 C# 数据结构:

    struct MyData
{
public MyData (int Count) : this ()
{
uData = new Single[Count];
}
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] uCode;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public byte[] uLabel;
public int uDate;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 37)]
public Single [] uData;
}

如果数据格式正确,该文件将由另一个应用程序读取,该应用程序可以从二进制文件中读取数据。我打印了两种结构类型的大小,它们看起来不错。但是,该应用程序无法读取输出文件。

所以我有两个问题:

  1. 我在 C 到 C# 转换中使用的数据类型和元组是否正确?

  2. 我使用 FileStream 和 BinaryWriter 写入二进制文件。所有数据( header 和后续数据)必须按顺序(连续)。当我动态创建和写入数据结构时,我不确定如何使用以下内容分配连续内存:

public static byte[] GetData(object obj)
{

var size = Marshal.SizeOf(obj.GetType());
var data = new byte[size];
IntPtr pnt = Marshal.AllocHGlobal(size);

try
{
Marshal.StructureToPtr(obj, pnt, true);
// Copy the array to unmanaged memory.
Marshal.Copy(pnt, data, 0, size);
return data;
}
finally
{
// Free the unmanaged memory.
Marshal.FreeHGlobal(pnt);
}
}

任何帮助将不胜感激!

[编辑]我添加了两个方法将特定的结构体数据转换为字节数组,但文件仍然无法读取:

   private byte[] DataToByteArray(MyData data)
{
int len = 0;
var size = Marshal.SizeOf(data.GetType());
var barray = new byte[size];
data.uCode.CopyTo(barray, 0);
len += data.uCode.Length;
data.uLabel.CopyTo(barray, len);
len += data.uLabel.Length;
BitConverter.GetBytes(0).CopyTo(barray, len);
len += data.uData.Length;
Buffer.BlockCopy(data.uData, 0, barray, len, data.uData.Length);

return barray;
}

private byte[] HeadToByteArray(Header data)
{
var size = Marshal.SizeOf(data.GetType());
var barray = new byte[size];
BitConverter.GetBytes(data.uSignature).CopyTo(barray, 0);
BitConverter.GetBytes(data.uRecordLength).CopyTo(barray, 4);

return barray;
}

【编辑2】下面是它在 C 中的工作原理:

#define     NQ_EX            'QN'
FILE *fout;
fopen_s(&fout, "path_to_the_file", "wb");
Header head = { val1, sizeof(MyData) };
fwrite(&head, sizeof(Header), 1, fout);

while (!stop && data_is_coming)
{
MyData data;
memset(&data, 0, sizeof(data));
data.uCode = NQ_EX;
sprintf_s(data.uLabel, "%s", getVal("field1"));
data.uData[0] = getVal("field2");
data.uData[1] = getVal("field3");
....
fwrite(&data, sizeof(MyData), 1, fout);
}

最佳答案

字节序似乎没问题。在 Jeroen 和其他人的帮助下进行一些更改和测试后,我能够使其工作。该问题是由于 Block.copy 方法造成的。我将其更改为 Array.copy,如下所示:

 private byte[] DataToByteArray(MyData data)
{
int len = 0;
var size = Marshal.SizeOf(data.GetType());
var barray = new byte[size];
data.uCode.CopyTo(barray, 0);
len += data.uCode.Length;
data.uLabel.CopyTo(barray, len);
len += data.uLabel.Length;
BitConverter.GetBytes(0).CopyTo(barray, len);
len += data.uData.Length;

for (int i = 0; i < data.uData.Length; i++)
Array.Copy(BitConverter.GetBytes(data.uData[i]), 0, barray, len+i * 4, 4);

return barray;
}

关于c# - 使用 C# 将连续的结构化数据写入二进制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40491797/

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