C# 如何将值结构的数组转换为字节?
我有一个值结构类型的C# 如何将值结构的数组转换为字节?,c#,.net,serialization,binary,C#,.net,Serialization,Binary,我有一个值结构类型的System.Array,如下所示: public value struct Position { int timestamp; float x; float y; } Position[] positions = new Position[1000 * 1000]; 在我用值初始化数组之后,我如何才能获得它的内容的字节[],而不一次序列化一个项目 在C++/CLI中,我将使用pin_ptr获取指向数组内容的指针,并从中复制数据。我可以用C#做这样
System.Array
,如下所示:
public value struct Position
{
int timestamp;
float x;
float y;
}
Position[] positions = new Position[1000 * 1000];
在我用值初始化数组之后,我如何才能获得它的内容的字节[]
,而不一次序列化一个项目
在C++/CLI中,我将使用pin_ptr
获取指向数组内容的指针,并从中复制数据。我可以用C#做这样的事吗
编辑:我需要将原始数据写入磁盘,就像它是一个C结构一样,没有任何序列化
我将这个问题标记为C#,以便更广泛地公开,但实际上我正在尝试序列化IronPython中的数据,因此这意味着我不能使用任何不安全的C#功能。也许这会有帮助:
[Serializable()]
public struct Position
{
int timestamp;
float x;
float y;
}
static void Main(string[] args)
{
var positions = new Position[1000 * 1000];
GetBytes(positions);
}
private static byte[] GetBytes(object obj)
{
using (var memoryStream = new System.IO.MemoryStream())
{
var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
binaryFormatter.Serialize(memoryStream, obj);
return memoryStream.ToArray();
}
}
我认为这相当于使用不安全C代码的C++/CLI pin#ptr:
以下是一种不需要不安全代码的方法: [更新以删除for循环并在一次过程中执行复制]
private static byte[] StructureToByteArray(Position[] posArray)
{
if (posArray == null || posArray.Length == 0)
{
return new byte[0];
}
var lenOfObject = Marshal.SizeOf(typeof(Position));
var len = lenOfObject * posArray.Length;
var arr = new byte[len];
var handle = GCHandle.Alloc(posArray, GCHandleType.Pinned);
try
{
var ptr = handle.AddrOfPinnedObject();
Marshal.Copy(ptr, arr, 0, len);
}
finally
{
handle.Free();
}
return arr;
}
Convert.GetBytes()
不工作吗?复制:@Default:如果您指的是BitConverter.GetBytes
,则不工作。它返回一个byte[]
,内部只有一个字节。您打算如何处理生成的字节数组?您需要将其存储在数据库中、发送到web服务还是???了解这一点可能有助于我们找到合适的解决方案。@competent_-tech:我已经更新了描述。我不认为序列化
格式化程序返回原始数据。这种方法确实提供了一个字节数组,并且只需要很少的编码工作,所以我认为这是完全正确的答案。当然,生成的字节数组不会尽可能小,因为它确实包含一些用于反序列化的类型信息。这取决于个人来决定是否适合他们的需要。我只是认为使用标准包I C#比使用不安全代码更好。我还认为,序列化对象时必须保存类型信息,这是事实。因此,字节数组可能更大,但我认为标准解决方案是更可取的。是否有必要将带有LayoutKind的StructLayout属性(顺序或显式)应用于Position结构,以便可靠地使用此方法?只是想知道。谢谢,但我不能用不安全的。我已经更新了说明,说明了原因。@Wily博士的徒弟,如果您要尝试与需要特定二进制布局的非托管代码进行互操作,我绝对建议您使用显式布局。我不确定自动布局定位的保证有多强。问题与不安全的答案相同:如果使用这种方法,将StructLayout
属性和LayoutKind
的Sequential
或Explicit
应用于位置
struct是否是一个好主意,或者这无关紧要?最好指定LayoutKind.Sequential
。由于结构经常用于互操作,因此它是C#/VB.NET编译器(可能还有其他编译器)的默认值,但不能保证它会保持不变。这贯穿于每一项。我想避免这种情况。
private static byte[] StructureToByteArray(Position[] posArray)
{
if (posArray == null || posArray.Length == 0)
{
return new byte[0];
}
var lenOfObject = Marshal.SizeOf(typeof(Position));
var len = lenOfObject * posArray.Length;
var arr = new byte[len];
var handle = GCHandle.Alloc(posArray, GCHandleType.Pinned);
try
{
var ptr = handle.AddrOfPinnedObject();
Marshal.Copy(ptr, arr, 0, len);
}
finally
{
handle.Free();
}
return arr;
}