其他分享
首页 > 其他分享> > 解析大型JSON文件,并将大量数据放在根对象的属性中

解析大型JSON文件,并将大量数据放在根对象的属性中

作者:互联网

我正在使用结构如下的JSON.NET框架解析相对较大(1.01GB)的JSON文件:

{
  "Stores": [
    {
        "Number": 1234,
        "City": "Denver",
        "County": "Denver",
        "Departments": [
            {
                "Name": "Deli",
                "Description": "sliced lunchmeat"
            },
            {
                "Name": "Produce",
                "Description": "fruit and vegetables"
            }
        ],
        "Telephone": "555-1212"
    },
    {
        "Number": 5678,
        "City": "Parker",
        "County": "Douglas",
        "Departments": [
            {
                "Name": "Seafood",
                "Description": "creatures of the sea"
            },
            {
                "Name": "Meat",
                "Description": ""
            }
        ],
        "Telephone": "555-2323"
    }
  ]
}

我试图一次解析整个JSON文件,但是遇到了内存不足异常,因此我现在试图以大块形式解析该文件.我可以使用下面的代码使它正常工作,但前提是要删除根Stores对象.我必须解析的实际文件具有根Stores对象,因此我需要弄清楚如何使其工作.我是JSON的新手,因此不胜感激.谢谢.

using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
using (StreamReader sr = new StreamReader(fs))
using (JsonTextReader reader = new JsonTextReader(sr))
{
    while (reader.Read())
    {
        DepartmentInfo = "";

        if (reader.TokenType == JsonToken.StartObject)
        {
            dynamic obj = JObject.Load(reader);

            City = obj.City.ToString();
            County = obj.County.ToString();

            foreach (var Department in obj.Departments)
            {
                DepartmentInfo += Department.ToString();
            }
        }
    }
}

更新:我更新了JSON以显示我正在使用的实际格式,它在Departments数组中缺少Description字段.另外,我在做什么方面还有一些背景信息-我正在将该文件加载到数据库中,并要求使其看起来尽可能靠近源文件,以便对其进行跟踪,然后在文件中进行进一步处理.数据库以将数据规范化为另一个数据模型,因此DepartmentInfo在设计上有点过时.最终代码如下.谢谢!

string DepartmentInfo = "";

using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
using (StreamReader sr = new StreamReader(fs))
using (JsonTextReader reader = new JsonTextReader(sr))
{
    while (reader.TokenType != JsonToken.StartArray)
        reader.Read();

    while(reader.Read())
    {
        DepartmentInfo = "";

        if (reader.TokenType == JsonToken.StartObject)
        {
            dynamic obj = JObject.Load(reader);

            var StoreNumber = obj["Number"];
            var City = obj["City"].ToString();
            var County = obj["County"].ToString();
            var PhoneNumber = obj["Telephone"];

            foreach (var Department in obj.Departments)
            {
                DepartmentInfo += ("Name: " + Department.Name.ToString() + ", Description: " + Department.Description.ToString() + " ");
            }


        }
    }
}

解决方法:

您走在正确的轨道上.您只需要一点代码就可以将阅读器推进到Stores数组的开头,然后使用已经拥有的代码从那里进行处理.这是修改后的代码:

using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
using (StreamReader sr = new StreamReader(fs))
using (JsonTextReader reader = new JsonTextReader(sr))
{
    // Advance the reader to start of first array, 
    // which should be value of the "Stores" property
    while (reader.TokenType != JsonToken.StartArray)
        reader.Read();

    // Now process each store individually
    while (reader.Read())
    {
        if (reader.TokenType == JsonToken.StartObject)
        {
            dynamic obj = JObject.Load(reader);

            // ...
        }
    }
}

这是working fiddle的演示概念.注意我使用的是硬编码的JSON字符串和MemoryStream而不是FileStream,但是结果是相同的.我还做了一些调整,使部门的输出更具可读性.

标签:json-net,c
来源: https://codeday.me/bug/20191119/2033802.html