使用根对象的属性中的大量数据分析大型 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 文件,但遇到了内存不足异常,所以我现在尝试分块解析文件。我能够使用以下代码使其工作,但前提是我删除根存储对象。我必须解析的实际文件具有根存储对象,因此我需要弄清楚如何使其工作。我对 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 以显示我正在使用的实际格式,它在部门数组中缺少描述字段。还有关于我正在做的事情的更多上下文 - 我正在将此文件加载到数据库中,并且需要使其看起来尽可能靠近源,以便可以对其进行跟踪,然后在数据库中进行进一步处理以将数据规范化为另一个数据模型,因此 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);
            // ...
        }
    }
}

这是一个演示概念的工作小提琴。 注意 我使用的是硬编码的 JSON 字符串和MemoryStream而不是FileStream,但结果是相同的。 我还进行了一些调整,以使部门输出更具可读性。

相关内容

  • 没有找到相关文章

最新更新