(de)使用 System.Text.Json 序列化流

(de)Serializing stream using System.Text.Json

我正在尝试使用 System.Text.Json 的 JsonSerializer 将对象序列化为 MemoryStream。我无法在文档中找到它的 implementation/method。有人可以使用 System.Text.Json 分享序列化和反序列化的示例实现吗?

更好的选择是使用 newtonsoft.json。

例子很多

不清楚问题出在哪里,或者缺少哪些文档和示例,因为 docs.microsoft.com 中有 多个 部分以及数百篇博客文章和文章。在文档中 JSON serialization and deserialization is a good place to start and How to serialize and deserialize (marshal and unmarshal) JSON in .NET includes the section Serialize to UTF8.

A MemoryStream is just a Stream wrapper over a byte[] array anyway, so serializing to a MemoryStream is the same as serializing to a byte[] array directly. This can be done with JsonSerializer.SerializeToUtf8Bytes:

byte[] jsonUtf8Bytes =JsonSerializer.SerializeToUtf8Bytes(weatherForecast);

最后,在 .NET 中,任何需要序列化的东西都通过 Reader 和 Writer 对象工作,例如 TextReader、StreamReader、TextReader 和 - 作家。在 JSON.NET 的情况下,这是通过 Utf8JsonWriter object. JsonSerializer.Serialize 具有写入 Utf8JsonWriter 的重载来完成的:

using var stream=File.OpenWrite(somePath);
using var writer=new Utf8JsonWriter(stream);
JsonSerializer.Serialize(writer,myObject);

这是 缓慢 使用 System.Text.Json 的方式。使用缓冲区意味着分配它们并清理它们,这是非常昂贵的,尤其是在 Web 应用程序中。出于这个原因,ASP.NET Core 使用 IO pipelines 而不是流来接收和发送数据到套接字,使用从缓冲池租用的可重用缓冲区并沿着 ASP.NET Core 管道中的每个步骤传递。传递 byte[] 缓冲区来复制它们的内容,因此 .NET Core 引入了 Span<>Memory<> 类型,它们表示 view 现有(可能池)缓冲区。这样,ASP.NET Core 传递缓冲区的那些“视图”,而不是缓冲区本身。

System.Text.Json 被构建为使用管道和可重用内存而不是流,允许 ASP.NET Core 在高流量网站中使用最少的内存和尽可能少的分配。 ASP.NET 核心使用 Utf8JsonWriter(IBufferWriter) constructor to write to the output pipeline through a PipeWriter.

我们可以使用相同的重载来写入具有 ArrayBufferWriter 的可重用缓冲区。这相当于使用 MemoryStream BUT 可以通过 ReadOnlySpan<byte>Memory<byte> 访问输出,因此不必复制它:

using var buffer=new ArrayBufferWriter<byte>(65536);
using var writer=new Utf8JsonWriter(buffer);
JsonSerializer.Serialize(writer,myObject);

ReadOnlySpan<byte> data=buffer.WrittenSpan;