为什么大多数序列化程序使用流而不是字节数组?
Why do most serializers use a stream instead of a byte array?
我目前正在开发套接字服务器,我想知道
为什么像
这样的序列化程序
都需要 Stream 而不是字节数组?
您可以轻松地在字节数组上创建流...但是字节数组本质上是大小受限的,其中流是开放式的...您需要多大就多大。一些序列化可能非常庞大。
编辑:另外,如果我需要实现某种序列化,我想针对最基本的抽象来做,避免在多个抽象上做。 Stream 是我的选择,因为很多东西都有流实现:内存、磁盘、网络等等。作为实施者,我得到了 "free".
这意味着您可以流式传输到任意目的地,而不是只是到内存。
如果要向文件写入内容,为什么要先在内存中创建一个完整的副本?在某些情况下,这可能会导致您使用 很多 的额外内存,从而可能导致失败。
如果要创建字节数组,只需使用 MemoryStream
:
var memoryStream = new MemoryStream();
serializer.Write(foo, memoryStream); // Or whatever you're using
var bytes = memoryStream.ToArray();
因此,通过 "you use streams" 的抽象,您可以轻松地使用内存 - 但如果抽象是 "you use a byte array",您甚至 被迫 使用内存如果你不想。
如果你使用 byte array/ buffer
你是在内存中临时工作并且你的大小有限
虽然流可以让您将内容存储在磁盘上,然后发送到其他计算机,例如互联网、串行端口等。流通常使用缓冲区来优化传输速度。
因此,如果您要处理大文件,流式处理会很有用
在依赖于机器的应用程序(例如缓冲区)中操作 ASCII(即 1 字节)字符串时,字节数组的使用频率更高。它们更适合低级应用程序,而 "streams" 是一种更通用的数据处理方式,可以实现更广泛的应用程序。此外,流是一种更抽象的查看数据的方式,它允许字符类型(UTF-8、UTF-16、ASCII 等)等因素由数据流用户不可见的代码处理。
@JonSkeet 的回答是正确的,但作为附录,如果您在制作临时流时遇到的问题是 "I don't like it because it's effort" 然后考虑编写扩展方法:
namespace Project.Extensions
{
public static class XmlSerialiserExtensions
{
public static void Serialise(this XmlSerializer serialiser, byte[] bytes, object obj)
{
using(var temp = new MemoryStream(bytes))
serialiser.Serialize(temp, obj);
}
public static object Deserialise(this XmlSerializer serialiser, byte[] bytes)
{
using(var temp = new MemoryStream(bytes))
return serialiser.Deserialize(temp);
}
}
}
所以你可以继续做
serialiser.Serialise(buffer, obj);
socket.Write(buffer);
或者
socket.Read(buffer);
var obj = serialiser.Deserialise(buffer);
我目前正在开发套接字服务器,我想知道 为什么像
这样的序列化程序都需要 Stream 而不是字节数组?
您可以轻松地在字节数组上创建流...但是字节数组本质上是大小受限的,其中流是开放式的...您需要多大就多大。一些序列化可能非常庞大。
编辑:另外,如果我需要实现某种序列化,我想针对最基本的抽象来做,避免在多个抽象上做。 Stream 是我的选择,因为很多东西都有流实现:内存、磁盘、网络等等。作为实施者,我得到了 "free".
这意味着您可以流式传输到任意目的地,而不是只是到内存。
如果要向文件写入内容,为什么要先在内存中创建一个完整的副本?在某些情况下,这可能会导致您使用 很多 的额外内存,从而可能导致失败。
如果要创建字节数组,只需使用 MemoryStream
:
var memoryStream = new MemoryStream();
serializer.Write(foo, memoryStream); // Or whatever you're using
var bytes = memoryStream.ToArray();
因此,通过 "you use streams" 的抽象,您可以轻松地使用内存 - 但如果抽象是 "you use a byte array",您甚至 被迫 使用内存如果你不想。
如果你使用 byte array/ buffer
你是在内存中临时工作并且你的大小有限
虽然流可以让您将内容存储在磁盘上,然后发送到其他计算机,例如互联网、串行端口等。流通常使用缓冲区来优化传输速度。
因此,如果您要处理大文件,流式处理会很有用
在依赖于机器的应用程序(例如缓冲区)中操作 ASCII(即 1 字节)字符串时,字节数组的使用频率更高。它们更适合低级应用程序,而 "streams" 是一种更通用的数据处理方式,可以实现更广泛的应用程序。此外,流是一种更抽象的查看数据的方式,它允许字符类型(UTF-8、UTF-16、ASCII 等)等因素由数据流用户不可见的代码处理。
@JonSkeet 的回答是正确的,但作为附录,如果您在制作临时流时遇到的问题是 "I don't like it because it's effort" 然后考虑编写扩展方法:
namespace Project.Extensions
{
public static class XmlSerialiserExtensions
{
public static void Serialise(this XmlSerializer serialiser, byte[] bytes, object obj)
{
using(var temp = new MemoryStream(bytes))
serialiser.Serialize(temp, obj);
}
public static object Deserialise(this XmlSerializer serialiser, byte[] bytes)
{
using(var temp = new MemoryStream(bytes))
return serialiser.Deserialize(temp);
}
}
}
所以你可以继续做
serialiser.Serialise(buffer, obj);
socket.Write(buffer);
或者
socket.Read(buffer);
var obj = serialiser.Deserialise(buffer);