2

大きな JSON ファイル (サイズが数百 MB) から JSON オブジェクトを反復処理できる JSON パーサーを探しています。以下のようにJson.NET からJsonTextReaderを試しました。

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);
}

しかし、トークンの後にトークンを返します。
トークンの代わりにオブジェクト全体が必要な場合、より簡単な方法はありますか?

4

3 に答える 3

2

次のような json 配列があるとします。

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

オブジェクト型のクラスを宣言します

public class TempClass
{
    public string text;
}

さて、逆シリアル化部分

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 クラス

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();
    }
}
于 2013-09-10T14:34:37.913 に答える
1

これは、私が独自のパーサー/デシリアライザーで考えた使用例の 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)
  ]
}

... これらの POCO に:

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

(具体的には、「FathersData」、「Father」、「Son」、「Daughter」)

そのサンプルには次のものも含まれています。

(1) Father[] 配列の相対アイテム インデックスに対するサンプル フィルター (たとえば、最初の 10 個だけを取得するため)、および

(2) それぞれの父親の逆シリアル化が返されるときに、父親の娘のプロパティを動的に設定する方法 (つまり、コールバックの目的で、呼び出し元がパーサーの Parse メソッドに渡すデリゲートのおかげです)。

残りのビットについては、以下を参照してください。

ParserTests.cs : static void FilteredFatherStreamTestDaughterMaidenNamesFixup()

( 829行目から904行目)

12MB から 180MB の JSON ファイルをいくつか解析し、そのコンテンツの任意のサブセットを POCO に逆シリアル化するために、私が控えめなラップトップ (*) で観察したパフォーマンス

(または緩く型付けされた辞書 ((文字列、オブジェクト) キーと値のペアのみ) への変換もサポートされています)

およそ 20MB/秒から 40MB/秒 (**) の範囲です。

(例: 12MB の JSON ファイルの場合、POCO に約 300 ミリ秒)

ここで入手可能な詳細情報:

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

'HTH、

(*) (Win7 64 ビット @ 2.5Ghz を実行)

(**) (スループットは、入力 JSON の形状/複雑さ (サブオブジェクトのネストの深さなど) やその他の要因に大きく依存します)

于 2014-05-19T06:58:36.663 に答える
1

このライブラリJSON.netを使用します。Nuget のコマンドは次のとおりです -> Install-Package Newtonsoft.Json

于 2013-09-10T09:23:08.893 に答える