为什么大多数序列化程序使用流而不是字节数组?

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);