我有一个巨大的 JSON 文件(数万个对象,>100 MB 文件),我正在尝试解析以提取特定对象。由于文件太大,我尝试仅反序列化我需要的特定部分(如果可能的话),而不必反序列化整个文件。
应根据特定属性的值找到所述对象"arena_id":xxxxx
包含在每个对象中,对象的格式如下(精简版本):
{"object":"card","id":"61a908e8-6952-46c0-94ec-3962b7a4caef","oracle_id":"e70f5520-1b9c-4351-8484-30f0dc692e01","multiverse_ids":[460007],"mtgo_id":71000,"arena_id":69421}
为了反序列化整个文件,我编写了以下代码:
public static RootObject GetCardFromBulkScryfall()
{
string s = null;
using (StreamReader streamReader = new StreamReader(Path.Combine(GetAppDataPath(), @"scryfall-default-cards.json")))
{
s = streamReader.ReadToEnd();
}
RootObject card = JsonConvert.DeserializeObject<RootObject>(s);
return card;
}
我什至不确定我想做的事情是否可行,但如果这不是我的问题,那么处理这么大的文件而不需要将其整个反序列化的最佳方法是什么。
Use JsonTextReader https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_JsonTextReader.htm with JsonTextWriter https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_JsonTextWriter.htm枚举对象,然后在其属性具有所需值时反序列化它们。
此代码在我的 PC 上处理 112MB JSON 文件时需要 16MB 内存。
如果您有疑问或需要修复,请告诉我。
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
try
{
string jsonFilePath = "1.json";
string propName = "arena_id";
RootObject[] objects = SearchObjectsWithProperty<RootObject, int>(jsonFilePath, propName, 69421, CancellationToken.None).ToArray();
System.Diagnostics.Debugger.Break();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
System.Diagnostics.Debugger.Break();
}
}
static IEnumerable<T> SearchObjectsWithProperty<T, V>(string jsonFilePath, string propName, V propValue, CancellationToken cancellationToken) where V : IEquatable<V>
{
using (TextReader tr = File.OpenText(jsonFilePath))
{
using (JsonTextReader jr = new JsonTextReader(tr))
{
StringBuilder currentObjectJson = new StringBuilder();
while (jr.Read())
{
cancellationToken.ThrowIfCancellationRequested();
if (jr.TokenType == JsonToken.StartObject)
{
currentObjectJson.Clear();
using (TextWriter tw = new StringWriter(currentObjectJson))
{
using (JsonTextWriter jw = new JsonTextWriter(tw))
{
jw.WriteToken(jr);
string currObjJson = currentObjectJson.ToString();
JObject obj = JObject.Parse(currObjJson);
if (obj[propName].ToObject<V>().Equals(propValue))
yield return obj.ToObject<T>();
}
}
}
}
}
}
}
}
public class RootObject
{
public string @object { get; set; }
public string id { get; set; }
public string oracle_id { get; set; }
public int[] multiverse_ids { get; set; }
public int mtgo_id { get; set; }
public int arena_id { get; set; }
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)