C#中的增量JSON解析

use*_*410 11 c# parsing json

我试图逐步解析JSON,即基于条件.

下面是我的json消息,我目前正在使用JavaScriptSerializer来反序列化消息.

string json = @"{"id":2,
"method":"add",
"params":
   {"object":
       {"name":"test"
        "id":"1"},
        "position":"1"}
  }";

JavaScriptSerializer js = new JavaScriptSerializer();
Message m = js.Deserialize<Message>(json);
Run Code Online (Sandbox Code Playgroud)

消息类如下所示:

 public class Message
 {
        public string id { get; set; }
        public string method { get; set; }
        public Params @params { get; set; }
        public string position { get; set; }
 }
public class Params
{
        public string name { get; set; }
        public string id{ get; set; 
}
Run Code Online (Sandbox Code Playgroud)

上面的代码解析消息没有问题.但它会立即解析整个JSON.我希望它仅在"method"参数的值为"add"时才进行解析.如果它不是"添加",那么我不希望它继续解析其余的消息.有没有办法根据C#中的条件进行增量解析?(环境:VS 2008与.Net 3.5)

Dav*_*ter 14

我不得不承认我对JavaScriptSerializer并不熟悉,但是如果你愿意使用JSON.net,它的JsonReader行为就像是一个DataReader.

using(var jsonReader = new JsonTextReader(myTextReader)){
  while(jsonReader.Read()){
    //evaluate the current node and whether it's the name you want
    if(jsonReader.TokenType.PropertyName=="add"){
      //do what you want
    } else {
      //break out of loop.
    }
  }
}
Run Code Online (Sandbox Code Playgroud)


Shi*_*hah 9

以下是我用来解析,加载和创建非常大的JSON文件的通用和简单方法.该代码现在使用了非常标准的JSON.Net库.不幸的是,文档不是很清楚如何做到这一点,但也不是很难弄清楚.

下面的代码假定您要将大量对象要序列化为JSON数组的情况,反之亦然.我们希望支持非常大的文件,这些文件的大小仅受存储设备(不是内存)的限制.因此,在序列化时,该方法需要IEnumerable<T>并且在反序列化时返回相同的内容.这样您就可以处理整个文件而不受内存的限制.

我已经将这段代码用于几GB的文件大小,并且性能合理.

//Serialize sequence of objects as JSON array in to a specified file
public static void SerializeSequenceToJson<T>(this IEnumerable<T> sequence, string fileName)
{
    using (var fileStream = File.CreateText(fileName))
        SerializeSequenceToJson(sequence, fileStream);
}

//Deserialize specified file in to IEnumerable assuming it has array of JSON objects
public static IEnumerable<T> DeserializeSequenceFromJson<T>(string fileName)
{
    using (var fileStream = File.OpenText(fileName))
        foreach (var responseJson in DeserializeSequenceFromJson<T>(fileStream))
            yield return responseJson;
}

//Utility methods to operate on streams instead of file
public static void SerializeSequenceToJson<T>(this IEnumerable<T> sequence, TextWriter writeStream, Action<T, long> progress = null)
{
    using (var writer = new JsonTextWriter(writeStream))
    {
        var serializer = new JsonSerializer();
        writer.WriteStartArray();
        long index = 0;
        foreach (var item in sequence)
        {
            if (progress != null)
                progress(item, index++);

            serializer.Serialize(writer, item);
        }
        writer.WriteEnd();
    }
}
public static IEnumerable<T> DeserializeSequenceFromJson<T>(TextReader readerStream)
{
    using (var reader = new JsonTextReader(readerStream))
    {
        var serializer = new JsonSerializer();
        if (!reader.Read() || reader.TokenType != JsonToken.StartArray)
            throw new Exception("Expected start of array in the deserialized json string");

        while (reader.Read())
        {
            if (reader.TokenType == JsonToken.EndArray) break;
            var item = serializer.Deserialize<T>(reader);
            yield return item;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Kev*_*ick 5

如果您看一下Json.NET,它会提供一个非缓存,仅向前的JSON解析器,以满足您的需求.

请参阅文档中JsonReaderJsonTextReader类.