2013-09-10 3 views
1

Я ищу JSON Parser, который может позволить мне выполнять итерацию через объекты JSON из большого файла JSON (с размером несколько сотен МБ). Я попытался JsonTextReader от Json.NET, как показано ниже:Чтение объектов JSON из большого файла

JsonTextReader reader = new JsonTextReader(new StringReader(json)); 
while (reader.Read()) 
{ 
    if (reader.Value != null) 
     Console.WriteLine("Token: {0}, Value: {1}", reader.TokenType, reader.Value); 
    else 
     Console.WriteLine("Token: {0}", reader.TokenType); 
} 

Но он возвращает маркер после маркеров.
Есть ли более простой способ, если мне нужен цельный объект вместо токенов?

+0

'JObject.Parse' – I4V

+1

Придётся попытался взглянуть на Newtonsoft JSON (https://json.codeplex.com/) – Zaksh

+0

@Zaksh Я пытаюсь же библиотеку Json.NET – Seenu

ответ

2

Предположим, у вас есть массив JSON, похожее на это:

[{"text":"0"},{"text":"1"}......] 

я объявить класс для типа объекта

public class TempClass 
{ 
    public string text; 
} 

Теперь deserializetion часть

JsonSerializer ser = new JsonSerializer(); 
ser.Converters.Add(new DummyConverter<TempClass>(t => 
    { 
     //A callback method 
     Console.WriteLine(t.text); 
    })); 

ser.Deserialize(new JsonTextReader(new StreamReader(File.OpenRead(fName))), 
       typeof(List<TempClass>)); 

И фиктивный класс JsonConverter к intercep т десериализации

public class DummyConverter<T> : JsonConverter 
{ 
    Action<T> _action = null; 
    public DummyConverter(Action<T> action) 
    { 
     _action = action; 
    } 
    public override bool CanConvert(Type objectType) 
    { 
     return objectType == typeof(TempClass); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     serializer.Converters.Remove(this); 
     T item = serializer.Deserialize<T>(reader); 
     _action(item); 
     return null; 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+0

В чем важность сериализатора.Конвертеры. Удалить (это); – Seenu

+1

@Seenu, если вы не удалите его, ниже строки ('T item = serializer.Deserialize (reader);') приводит к бесконечной рекурсии. – I4V

1

Я бы использовал эту библиотеку JSON.net. Команда для NuGet выглядит следующим образом -> Install-Package Newtonsoft.Json

+0

Я использую то же самое – Seenu

1

Это один из вариантов использования, я предусматриваемых для моего собственного парсера/десериализации.

Я недавно сделал простой пример (путем подачи парсер с JSON текстом, который читается через в StreamReader) из десериализации этой формы JSON:

{ 
"fathers" : [ 
{ 
    "id" : 0, 
    "married" : true, 
    "name" : "John Lee", 
    "sons" : [ 
    { 
     "age" : 15, 
     "name" : "Ronald" 
     } 
    ], 
    "daughters" : [ 
    { 
     "age" : 7, 
     "name" : "Amy" 
     }, 
    { 
     "age" : 29, 
     "name" : "Carol" 
     }, 
    { 
     "age" : 14, 
     "name" : "Barbara" 
     } 
    ] 
    }, 
{ 
    "id" : 1, 
    "married" : false, 
    "name" : "Kenneth Gonzalez", 
    "sons" : [ 
    ], 
    "daughters" : [ 
    ] 
    }, 
{ 
    "id" : 2, 
    "married" : false, 
    "name" : "Larry Lee", 
    "sons" : [ 
    { 
     "age" : 4, 
     "name" : "Anthony" 
     }, 
    { 
     "age" : 2, 
     "name" : "Donald" 
     } 
    ], 
    "daughters" : [ 
    { 
     "age" : 7, 
     "name" : "Elizabeth" 
     }, 
    { 
     "age" : 15, 
     "name" : "Betty" 
     } 
    ] 
    }, 

    //(... etc) 
    ] 
} 

... в эту Pocos:

https://github.com/ysharplanguage/FastJsonParser#POCOs

(то есть, в частности: "FathersData", "Отец", "Сын", "дочка")

Этот образец также представляет:

(1) образец фильтр по индексу относительного пункта в [] массиве отца (например, для извлечения только первые 10), и

(2), как заполнить динамически свойство дочерея отца , так как десериализация их соответствующих отцов возвращает (то есть, благодаря делегату, что вызывающий абонент переходит к методу анализа парсера для целей обратного вызова).

Для остальных битов, см:

ParserTests.cs : static void FilteredFatherStreamTestDaughterMaidenNamesFixup()

(строки #829 к #904)

спектакля я наблюдать на мой скромный ноутбук (*) для разбора некоторые ~ 12MB до ~ 180 Мбайт файлов JSON и десериализация произвольного подмножества их содержимого в POCOs

(или в свободно-типизированные словари (только пары (строки, объекта) ключ/значение) также поддерживаются)

находится в любом месте стадиона от ~ 20 МБ/с до 40 МБ/с (**).

(например, ~ 300 миллисекунд в случае файла 12MB JSON, в Pocos)

Более подробная информация доступны здесь:

https://github.com/ysharplanguage/FastJsonParser#Performance

«HTH,

(*) (работает Win7 64bit @ 2.5Ghz)

(**) (пропускная способность вполне зависит от входной формы/сложности JSON, например, под-объектов n глубина esting и другие факторы)

Смежные вопросы