我正在使用结构如下的 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
,但结果是相同的。 我还进行了一些调整,以使部门输出更具可读性。