C# 使用JSON.NET一次序列化一个对象数组

C# 使用JSON.NET一次序列化一个对象数组,c#,javascript,.net,json,json.net,C#,Javascript,.net,Json,Json.net,我尝试将多个项目序列化为json,并将它们格式化为一个数组 _jsonWriter = new JsonTextWriter(new StreamWriter("Output.json"))); DataGatherer.ItemGathered += item => { _jsonSerializer.Serialize(_jsonWriter, item); _jsonWriter.Flush(); }; 它是基于事件的,因为它有很多数据不能作为一个整体保存在内存中。

我尝试将多个项目序列化为json,并将它们格式化为一个数组

_jsonWriter = new JsonTextWriter(new StreamWriter("Output.json")));
DataGatherer.ItemGathered += item =>
{
    _jsonSerializer.Serialize(_jsonWriter, item);
    _jsonWriter.Flush();
};
它是基于事件的,因为它有很多数据不能作为一个整体保存在内存中。但我需要将每个项序列化为一个文件,并将其格式化为数组

_jsonWriter = new JsonTextWriter(new StreamWriter("Output.json")));
DataGatherer.ItemGathered += item =>
{
    _jsonSerializer.Serialize(_jsonWriter, item);
    _jsonWriter.Flush();
};
目前,这一成果如下:

{
  "Id": 218515,
  "Name": "A"
}{
  "Id": 118647,
  "Name": "B"
}
由于序列化程序将每个项序列化为对象,因此不知道它是数组

_jsonWriter = new JsonTextWriter(new StreamWriter("Output.json")));
DataGatherer.ItemGathered += item =>
{
    _jsonSerializer.Serialize(_jsonWriter, item);
    _jsonWriter.Flush();
};
那么,我如何告诉JSON.Net序列化程序将每个项作为数组的一项处理,并将数据格式化为:

[{ "Id": 218515, "Name": "A"},{"Id": 118647,"Name": "B"}]

谢谢你的提示

为什么不构建一个
IEnumerable
。 它不需要读取内存中的所有集合,当您将其交给serialiazer时,它将被解析为数组。 一个简单的方法是用一个简单的
收益回报率

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

以下是我对
jsonimwriter
的想法:

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();
    }
}
然后按如下方式设置事件处理程序:

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

DataGatherer.ItemGathered += item =>
{
    _itemWriter.WriteItem(item);
};
下面是一个简短的演示,使用模拟数据采集程序来代替您的:

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

非常感谢你!我所得到的最详细的答案和代码示例:)非常好用,而且非常简单,尽管我认为Json.net提供了内置的方法来完成这项工作。如果可以同时在内存中保存所有项,那么只需将它们添加到列表中,并在完成收集后序列化即可。但是,一旦你有太多的项目无法存储在内存中,你就必须发挥创造力,想出一个不同的方法(因此这个解决方案)。我很高兴它对你有用!