使用JSON.NET一次序列化一组对象

das*_*dot 5 .net javascript c# json json.net

我尝试将多个项目序列化为json,并将其格式化为数组。

它是基于事件的,因为它的大量数据无法作为一个整体收集在内存中。但是我需要将每个项目序列化为一个文件,并将其格式化为数组。

_jsonWriter = new JsonTextWriter(new StreamWriter("Output.json")));
DataGatherer.ItemGathered += item =>
{
    _jsonSerializer.Serialize(_jsonWriter, item);
    _jsonWriter.Flush();
};
Run Code Online (Sandbox Code Playgroud)

当前,此输出如下:

{
  "Id": 218515,
  "Name": "A"
}{
  "Id": 118647,
  "Name": "B"
}
Run Code Online (Sandbox Code Playgroud)

由于序列化程序将每个项目序列化为一个对象,因此不知道其数组。

因此,我如何告诉JSON.Net序列化程序将每个项目作为数组的一个项目进行处理,并格式化数据,如下所示:

[{ "Id": 218515, "Name": "A"},{"Id": 118647,"Name": "B"}]
Run Code Online (Sandbox Code Playgroud)

感谢您的提示!

Bri*_*ers 6

我会创建一个简单的JsonItemWriter类来包装JsonTextWriter. 该类只需要跟踪是否有任何项目已写入输出。如果没有,请在写入项目之前使用内部 JsonTextWriter 将 StartArray 写入流。当外部 ItemWriter 关闭时,将 EndArray 写入流。然后更改您的事件处理程序以使用 ItemWriter 而不是 JsonTextWriter。

这是我想到的JsonItemWriter

class JsonItemWriter
{
    private JsonTextWriter innerWriter;
    private JsonSerializer serializer;

    public JsonItemWriter(JsonTextWriter innerWriter, JsonSerializer serializer)
    {
        this.innerWriter = innerWriter;
        this.serializer = serializer;
    }

    public void WriteItem(object item)
    {
        if (innerWriter.WriteState == Newtonsoft.Json.WriteState.Start)
        {
            innerWriter.WriteStartArray();
        }
        serializer.Serialize(innerWriter, item);
        innerWriter.Flush();
    }

    public void Close()
    {
        innerWriter.WriteEndArray();
        innerWriter.Close();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后像这样设置你的事件处理程序:

_jsonWriter = new JsonTextWriter(new StreamWriter("Output.json"));
_itemWriter = new JsonItemWriter(_jsonWriter, _jsonSerializer);

DataGatherer.ItemGathered += item =>
{
    _itemWriter.WriteItem(item);
};
Run Code Online (Sandbox Code Playgroud)

这是一个使用模拟 DataGatherer 代替您的简短演示:

class Program
{
    static void Main(string[] args)
    {
        JsonSerializer jsonSerializer = new JsonSerializer();
        JsonTextWriter jsonWriter = new JsonTextWriter(new StreamWriter("Output.json"));
        JsonItemWriter itemWriter = new JsonItemWriter(jsonWriter, jsonSerializer);

        MockDataGatherer gatherer = new MockDataGatherer();
        gatherer.ItemGathered += item =>
        {
            itemWriter.WriteItem(item);
        };

        var items = new[]
        {
            new { Id = 218515, Name = "A" },
            new { Id = 118647, Name = "B" }
        };
        gatherer.SimulateReceivingItems(items);

        itemWriter.Close();

        using (StreamReader reader = new StreamReader("Output.json"))
        {
            Console.WriteLine(reader.ReadToEnd());
        }
    }
}

class MockDataGatherer
{
    public void SimulateReceivingItems(IEnumerable<object> items)
    {
        foreach (object item in items)
        {
            ItemGathered(item);
        }
    }

    public event ItemGatheredEventHandler ItemGathered;
    public delegate void ItemGatheredEventHandler(object item);
}
Run Code Online (Sandbox Code Playgroud)

这是上面的输出(注意对象现在被包裹在一个数组中):

[{"Id":218515,"Name":"A"},{"Id":118647,"Name":"B"}]
Run Code Online (Sandbox Code Playgroud)