C# 从不同对象构造字节数组的舒适方式
C# comfortable way to construct byte array from different objects
我正在寻找一种快速简单地实施此范例的方法:
MyByteArray mb = new MyByteArray();
mb.Add<byte>(bytevalue);
mb.Add<float>(floatvalue);
mb.Add<string>(str);
mb.Add<MyClass>(object);
然后从 mb 中获取 byte[],通过 RPC 调用将其作为字节数据包发送(使用相同的技术在另一端解码)。
我找到了 MemoryStream,但对于这个简单的操作来说它看起来开销太大了。
你能帮帮我吗?谢谢。
你要找的是BinaryWritter。但出于纯粹的逻辑原因,它仍然需要一个 Stream 来写入。唯一符合您需要的 Stream 是 MemoryStream。
你害怕性能开销吗?您可以从现有字节数组创建 MemoryStream;
byte [] buffer = new byte[1024];
using (var memoryStream = new MemoryStream(buffer))
{
using (var binaryWriter = new BinaryWriter(memoryStream))
{
binaryWriter.Write(1.2F); // float
binaryWriter.Write(1.9D); // double
binaryWriter.Write(1); // integer
binaryWriter.Write("str"); // string
}
}
// buffer is filled with your data now.
这看起来像是 Protocol Buffers 的情况,您可以查看 protobuf-net。
首先,让我们装饰类。
[ProtoContract]
class User
{
[ProtoMember(1)]
public int Id { get; set; }
[ProtoMember(2)]
public string Name { get; set; }
}
[ProtoContract]
class Message
{
[ProtoMember(1)]
public byte Type { get; set; }
[ProtoMember(2)]
public float Value { get; set; }
[ProtoMember(3)]
public User Sender { get; set; }
}
然后我们创建消息。
var msg = new Message
{
Type = 1,
Value = 1.1f,
Sender = new User
{
Id = 8,
Name = "user"
}
};
现在,我们可以使用 ProtoBuf 的序列化器来完成我们所有的工作。
// memory
using (var mem = new MemoryStream())
{
Serializer.Serialize<Message>(mem, msg);
var bytes = mem.GetBuffer();
}
// file
using (var file = File.Create("message.bin")) Serializer.Serialize<Message>(file, msg);
实现此目的的一个棘手方法是在 .net
中结合使用内置 class
class Program
{
static void Main(string[] args)
{
Program program = new Program();
var listBytes = new List<byte>();
listBytes.Add( program.CastToBytes("test"));
listBytes.Add(program.CastToBytes(5));
}
备注
对于自定义对象,您必须定义 implicit operator
属性或所有对象的转换方式
public byte[] CastToBytes<T>(T value)
{
//this will cover most of primitive types
if (typeof(T).IsValueType)
{
return BitConverter.GetBytes((dynamic)value);
}
if (typeof(T) == typeof(string))
{
return Encoding.UTF8.GetBytes((dynamic) value);
}
//for a custom object you have to define the rules
else
{
var formatter = new BinaryFormatter();
var memoryStream = new MemoryStream();
formatter.Serialize(memoryStream, value);
return memoryStream.GetBuffer();
}
}
}
我正在寻找一种快速简单地实施此范例的方法:
MyByteArray mb = new MyByteArray();
mb.Add<byte>(bytevalue);
mb.Add<float>(floatvalue);
mb.Add<string>(str);
mb.Add<MyClass>(object);
然后从 mb 中获取 byte[],通过 RPC 调用将其作为字节数据包发送(使用相同的技术在另一端解码)。
我找到了 MemoryStream,但对于这个简单的操作来说它看起来开销太大了。
你能帮帮我吗?谢谢。
你要找的是BinaryWritter。但出于纯粹的逻辑原因,它仍然需要一个 Stream 来写入。唯一符合您需要的 Stream 是 MemoryStream。
你害怕性能开销吗?您可以从现有字节数组创建 MemoryStream;
byte [] buffer = new byte[1024];
using (var memoryStream = new MemoryStream(buffer))
{
using (var binaryWriter = new BinaryWriter(memoryStream))
{
binaryWriter.Write(1.2F); // float
binaryWriter.Write(1.9D); // double
binaryWriter.Write(1); // integer
binaryWriter.Write("str"); // string
}
}
// buffer is filled with your data now.
这看起来像是 Protocol Buffers 的情况,您可以查看 protobuf-net。
首先,让我们装饰类。
[ProtoContract]
class User
{
[ProtoMember(1)]
public int Id { get; set; }
[ProtoMember(2)]
public string Name { get; set; }
}
[ProtoContract]
class Message
{
[ProtoMember(1)]
public byte Type { get; set; }
[ProtoMember(2)]
public float Value { get; set; }
[ProtoMember(3)]
public User Sender { get; set; }
}
然后我们创建消息。
var msg = new Message
{
Type = 1,
Value = 1.1f,
Sender = new User
{
Id = 8,
Name = "user"
}
};
现在,我们可以使用 ProtoBuf 的序列化器来完成我们所有的工作。
// memory
using (var mem = new MemoryStream())
{
Serializer.Serialize<Message>(mem, msg);
var bytes = mem.GetBuffer();
}
// file
using (var file = File.Create("message.bin")) Serializer.Serialize<Message>(file, msg);
实现此目的的一个棘手方法是在 .net
中结合使用内置 class class Program
{
static void Main(string[] args)
{
Program program = new Program();
var listBytes = new List<byte>();
listBytes.Add( program.CastToBytes("test"));
listBytes.Add(program.CastToBytes(5));
}
备注
对于自定义对象,您必须定义 implicit operator
属性或所有对象的转换方式
public byte[] CastToBytes<T>(T value)
{
//this will cover most of primitive types
if (typeof(T).IsValueType)
{
return BitConverter.GetBytes((dynamic)value);
}
if (typeof(T) == typeof(string))
{
return Encoding.UTF8.GetBytes((dynamic) value);
}
//for a custom object you have to define the rules
else
{
var formatter = new BinaryFormatter();
var memoryStream = new MemoryStream();
formatter.Serialize(memoryStream, value);
return memoryStream.GetBuffer();
}
}
}