将任何对象转换为 byte[]
我正在编写一个 TCP 连接原型,但在均匀化要发送的数据时遇到了一些问题。
目前,我只发送字符串,但将来我们希望能够发送任何对象。
目前代码非常简单,因为我认为所有内容都可以转换为字节数组:
void SendData(object headerObject, object bodyObject)
{
byte[] header = (byte[])headerObject; //strings at runtime,
byte[] body = (byte[])bodyObject; //invalid cast exception
// Unable to cast object of type 'System.String' to type 'System.Byte[]'.
...
}
这当然可以很容易地用 a 解决
if( state.headerObject is System.String ){...}
问题是,如果我这样做,我需要检查每种类型的对象不能在运行时转换为 byte[]。
由于我不知道每个不能在运行时转换为 byte[] 的对象,所以这确实不是一个选择。
在 C# .NET 4.0 中,如何将任何对象转换为字节数组?
I am writing a prototype TCP connection and I am having some trouble homogenizing the data to be sent.
At the moment, I am sending nothing but strings, but in the future we want to be able to send any object.
The code is quite simple at the moment, because I thought everything could be cast into a byte array:
void SendData(object headerObject, object bodyObject)
{
byte[] header = (byte[])headerObject; //strings at runtime,
byte[] body = (byte[])bodyObject; //invalid cast exception
// Unable to cast object of type 'System.String' to type 'System.Byte[]'.
...
}
This of course is easily enough solved with a
if( state.headerObject is System.String ){...}
The problem is, if I do it that way, I need to check for EVERY type of object that can't be cast to a byte[] at runtime.
Since I do not know every object that can't be cast into a byte[] at runtime, this really isn't an option.
How does one convert any object at all into a byte array in C# .NET 4.0?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
使用
BinaryFormatter
:请注意,
obj
以及obj
中的任何属性/字段(等等所有属性/字段)都需要标记为Serialized
属性 成功序列化。Use the
BinaryFormatter
:Note that
obj
and any properties/fields withinobj
(and so-on for all of their properties/fields) will all need to be tagged with theSerializable
attribute to successfully be serialized with this.查看这篇文章:http://www.morgantechspace.com/ 2013/08/convert-object-to-byte-array-and-vice.html
使用以下代码
checkout this article :http://www.morgantechspace.com/2013/08/convert-object-to-byte-array-and-vice.html
Use the below code
就像其他人之前所说的那样,您可以使用二进制序列化,但它可能会产生额外的字节或被反序列化为具有不完全相同数据的对象。另一方面,使用反射相当复杂且非常慢。
还有另一种解决方案可以严格地将对象转换为字节,反之亦然 - 编组:
并将字节转换为对象:
与您自己的逐个序列化字段相比,对小对象和结构使用这种方法明显更慢并且部分不安全(因为从/到非托管内存的双重复制),但这是将对象严格转换为 byte[] 而不实现序列化且不使用 [Serialized] 属性的最简单方法。
Like others have said before, you could use binary serialization, but it may produce an extra bytes or be deserialized into an objects with not exactly same data. Using reflection on the other hand is quite complicated and very slow.
There is an another solution that can strictly convert your objects to bytes and vise-versa - marshalling:
And to convert bytes to object:
It's noticeably slower and partly unsafe to use this approach for small objects and structs comparing to your own serialization field by field (because of double copying from/to unmanaged memory), but it's easiest way to strictly convert object to byte[] without implementing serialization and without [Serializable] attribute.
使用
Encoding.UTF8.GetBytes
比使用MemoryStream
更快。在这里,我使用 NewtonsoftJson 将输入对象转换为 JSON 字符串,然后从 JSON 字符串获取字节。
@Daniel DiPaolo 版本与此版本的基准
Using
Encoding.UTF8.GetBytes
is faster than usingMemoryStream
.Here, I am using NewtonsoftJson to convert input object to JSON string and then getting bytes from JSON string.
Benchmark for @Daniel DiPaolo's version with this version
您正在寻找的是序列化。 .Net 平台有多种可用的序列化形式
byte[]
What you're looking for is serialization. There are several forms of serialization available for the .Net platform
byte[]
您可以像下面的代码一样使用它。
You can use it like below code.
扩展类中的组合解决方案:
Combined Solutions in Extensions class:
像这样简单的事情怎么样?
How about something simple like this?
您可以使用内置序列化工具 在框架中并序列化为 MemoryStream。这可能是最直接的选项,但可能会产生比您的场景严格需要的更大的 byte[]。
如果是这种情况,您可以利用反射来迭代要序列化的对象中的字段和/或属性,并将它们手动写入 MemoryStream,如果需要序列化非平凡类型,则递归调用序列化。此方法更复杂,需要更多时间来实现,但允许您更好地控制序列化流。
You could use the built-in serialization tools in the framework and serialize to a MemoryStream. This may be the most straightforward option, but might produce a larger byte[] than may be strictly necessary for your scenario.
If that is the case, you could utilize reflection to iterate over the fields and/or properties in the object to be serialized and manually write them to the MemoryStream, calling the serialization recursively if needed to serialize non-trivial types. This method is more complex and will take more time to implement, but allows you much more control over the serialized stream.
我宁愿使用表达“序列化”而不是“转换为字节”。序列化对象意味着将其转换为字节数组(或 XML 或其他内容),可以在远程设备上使用该数组来重新构造该对象。在 .NET 中,
Serialized
属性 标记其对象可以序列化的类型。I'd rather use the expression "serialization" than "casting into bytes". Serializing an object means converting it into a byte array (or XML, or something else) that can be used on the remote box to re-construct the object. In .NET, the
Serializable
attribute marks types whose objects can be serialized.另一种实现使用 Newtonsoft.Json 二进制 JSON,不需要使用 [Serializable] 属性标记所有内容。唯一的缺点是对象必须包装在匿名类中,因此通过二进制序列化获得的字节数组可能与此不同。
使用匿名类是因为 BSON 应该以类或数组开头。
我没有尝试将 byte[] 反序列化回对象,不确定它是否有效,但测试了转换为 byte[] 的速度,它完全满足我的需求。
One additional implementation, which uses Newtonsoft.Json binary JSON and does not require marking everything with the [Serializable] attribute. Only one drawback is that an object has to be wrapped in anonymous class, so byte array obtained with binary serialization can be different from this one.
Anonymous class is used because BSON should start with a class or array.
I have not tried to deserialize byte[] back to object and not sure if it works, but have tested the speed of conversion to byte[] and it completely satisfies my needs.
将对象转换为字节数组的替代方法:
Alternative way to convert object to byte array: