【问题标题】:Writing JSON to a stream without buffering the string in memory将 JSON 写入流而不在内存中缓冲字符串
【发布时间】:2013-08-16 09:20:41
【问题描述】:

我想通过显式构建文档将 JSON 写入 Stream。例如:

var stream = ...;
var writer = new JsonWriter(stream);

writer.BeginArray();
{
  writer.BeginObject();
  {
    writer.String("foo");
    writer.Number(1);
    writer.String("bar");
    writer.Number(2.3);
  }
  writer.EndObject();
}
writer.EndArray();

这会产生:

[
  {
    "foo": 1,
    "bar": 2.3
  }
]

这种方法的好处是不需要在内存中缓冲任何内容。在我的情况下,我正在向流中写入大量 JSON。诸如this one 之类的解决方案涉及在内存中创建所有对象,然后将它们序列化为内存中的一个大字符串,最后将该字符串写入流和垃圾收集,可能来自LOH。我想保持低内存使用,在从另一个文件/DB/etc 流中读取数据的同时写出元素。

这种方法在 C++ 中可以通过 rapidjson library 获得。

我已经为此搜索了很多,但没有找到解决方案。

【问题讨论】:

    标签: c# .net json io


    【解决方案1】:

    事实证明,我需要在 Google 上多花一点时间。

    JSON.NET 确实通过其JsonWriter 类支持这一点。

    我的例子会写成:

    Stream stream = ...;
    
    using (var streamWriter = new StreamWriter(stream))
    using (var writer = new JsonTextWriter(streamWriter))
    {
        writer.Formatting = Formatting.Indented;
    
        writer.WriteStartArray();
        {
            writer.WriteStartObject();
            {
                writer.WritePropertyName("foo");
                writer.WriteValue(1);
                writer.WritePropertyName("bar");
                writer.WriteValue(2.3);
            }
            writer.WriteEndObject();
        }
        writer.WriteEndArray();
    }
    

    【讨论】:

    • 为什么要使用那些不必要的{}s?
    • 为什么我要手动显式编写所有元素而不是简单地执行jsonSerializer.Serialize(jsonTextWriter,obj)
    • @I4V -- {} 是为了便于阅读,是可选的。在一个重要的例子中,他们真的可以提供帮助。如果您要编写许多遵循简单重复格式的元素,则手动编写元素是一个好主意。例如,如果您使用来自SqlDataReader 的 100,000 个元素将 JSON 写入 HTTP 响应流,则以这种方式写入可避免遇到 OutOfMemoryException,即使您没有 OOME,您的 Web 服务器也会执行得更好.所以,这取决于你的情况的要求。
    • @I4V,另外,在我的例子中,我使用了访问者模式类型排列,其中使用 JsonWriter 提供了一个很好的抽象,允许不同的处理程序编写他们想要的任何内容。
    • @I4V 此外,这是一种性能更高的方法。序列化总是需要很多开销。通过仅手动写入必要的数据,您可以避免大量工作。毕竟自动序列化确实需要检查某些属性并分析对象的结构,这确实比手动编写它花费更多的时间。在我的项目中,我确实手动编写了我的文件,因为它可能需要很长时间才能处理大量数据。对不起,我知道这个线程是旧的。但我认为这值得一提。
    猜你喜欢
    • 2013-01-16
    • 1970-01-01
    • 2021-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-13
    • 1970-01-01
    相关资源
    最近更新 更多