問題描述
到目前為止,我已經使用了 Json.NET 的JsonConvert.Deserialize(json)"方法,效果很好,老實說,我不需要更多的東西.
I have used the "JsonConvert.Deserialize(json)" method of Json.NET so far which worked quite well and to be honest, I didn't need anything more than this.
我正在開發一個后臺(控制臺)應用程序,該應用程序不斷從不同的 URL 下載 JSON 內容,然后將結果反序列化為 .NET 對象列表.
I am working on a background (console) application which constantly downloads the JSON content from different URLs, then deserializes the result into a list of .NET objects.
using (WebClient client = new WebClient())
{
string json = client.DownloadString(stringUrl);
var result = JsonConvert.DeserializeObject<List<Contact>>(json);
}
上面的簡單代碼片段可能看起來并不完美,但它確實可以完成工作.當文件很大(15,000 個聯系人 - 48 MB 文件)時,JsonConvert.DeserializeObject 不是解決方案,并且該行會引發 JsonReaderException 異常類型.
The simple code snippet above doesn't probably seem perfect, but it does the job. When the file is large (15,000 contacts - 48 MB file), JsonConvert.DeserializeObject isn't the solution and the line throws an exception type of JsonReaderException.
下載的 JSON 內容是一個數組,這就是示例的樣子.Contact 是反序列化 JSON 對象的容器類.
The downloaded JSON content is an array and this is how a sample looks like. Contact is a container class for the deserialized JSON object.
[
{
"firstname": "sometext",
"lastname": "sometext"
},
{
"firstname": "sometext",
"lastname": "sometext"
},
{
"firstname": "sometext",
"lastname": "sometext"
},
{
"firstname": "sometext",
"lastname": "sometext"
}
]
我最初的猜測是內存不足.只是出于好奇,我嘗試將其解析為 JArray,這也導致了同樣的異常.
My initial guess is it runs out of memory. Just out of curiosity, I tried to parse it as JArray which caused the same exception too.
我已經開始深入研究 Json.NET 文檔并閱讀類似的主題.由于我還沒有設法產生一個可行的解決方案,我決定在這里發布一個問題.
I have started to dive into Json.NET documentation and read similar threads. As I haven't managed to produce a working solution yet, I decided to post a question here.
更新:在逐行反序列化時,我得到了同樣的錯誤:[.Path '', line 600003, position 1."所以下載了其中兩個并在記事本++中檢查了它們.我注意到如果數組長度超過 12,000,則在第 12000 個元素之后,["關閉,另一個數組開始.換句話說,JSON 看起來就像這樣:
UPDATE: While deserializing line by line, I got the same error: " [. Path '', line 600003, position 1." So downloaded two of them and checked them in Notepad++. I noticed that if the array length is more than 12,000, after 12000th element, the "[" is closed and another array starts. In other words, the JSON looks exactly like this:
[
{
"firstname": "sometext",
"lastname": "sometext"
},
{
"firstname": "sometext",
"lastname": "sometext"
},
{
"firstname": "sometext",
"lastname": "sometext"
},
{
"firstname": "sometext",
"lastname": "sometext"
}
]
[
{
"firstname": "sometext",
"lastname": "sometext"
},
{
"firstname": "sometext",
"lastname": "sometext"
},
{
"firstname": "sometext",
"lastname": "sometext"
},
{
"firstname": "sometext",
"lastname": "sometext"
}
]
推薦答案
正如您在更新中正確診斷的那樣,問題是 JSON 有一個結束 ]
緊跟一個開始 [
開始下一組.這種格式在整體上會使 JSON 無效,這就是 Json.NET 拋出錯誤的原因.
As you've correctly diagnosed in your update, the issue is that the JSON has a closing ]
followed immediately by an opening [
to start the next set. This format makes the JSON invalid when taken as a whole, and that is why Json.NET throws an error.
幸運的是,這個問題似乎經常出現,以至于 Json.NET 實際上有一個特殊的設置來處理它.如果直接使用 JsonTextReader
讀取 JSON,可以將 SupportMultipleContent
標志設置為 true
,然后使用循環反序列化每個項個人.
Fortunately, this problem seems to come up often enough that Json.NET actually has a special setting to deal with it. If you use a JsonTextReader
directly to read the JSON, you can set the SupportMultipleContent
flag to true
, and then use a loop to deserialize each item individually.
這應該允許您以高效的內存方式成功處理非標準 JSON,而不管有多少數組或每個數組中有多少項.
This should allow you to process the non-standard JSON successfully and in a memory efficient manner, regardless of how many arrays there are or how many items in each array.
using (WebClient client = new WebClient())
using (Stream stream = client.OpenRead(stringUrl))
using (StreamReader streamReader = new StreamReader(stream))
using (JsonTextReader reader = new JsonTextReader(streamReader))
{
reader.SupportMultipleContent = true;
var serializer = new JsonSerializer();
while (reader.Read())
{
if (reader.TokenType == JsonToken.StartObject)
{
Contact c = serializer.Deserialize<Contact>(reader);
Console.WriteLine(c.FirstName + " " + c.LastName);
}
}
}
完整演示:https://dotnetfiddle.net/2TQa8p
這篇關于在 .NET 中解析大型 JSON 文件的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!