将非终止流中的对象集合转换为IObservable

时间:2013-03-30 14:28:22

标签: c# stream json.net deserialization system.reactive

我有一个Stream,其中包含序列化为JSON的对象集合,例如:

{"Name":"Alice","Age":20}{"Name":"Bob","Age":30}{"Name":"Charlie","Age":35}{"Name":"Danielle","Age":50}...

此流可能非常大,因此我希望在项目进入时处理这些项目,而不是将整个流程读入字符串。此外,如果流是网络流,它将无限期地打开。

有些对象可能非常复杂,所以我想利用JSON.NET提供的JSON序列化。

有没有办法可以使用Newtonsoft Json将流转换为IObservable<Person>并在项目到达时以反应方式处理这些项目?

1 个答案:

答案 0 :(得分:4)

如果您可以修改输入以使其看起来像JSON数组,那么您可以直接使用JsonTextReader来读取数组部分,然后使用JsonSerializer来读取数组中的对象。 / p>

这样,结果可以流式传输,而您不必处理所有反序列化。

生成IObservable的方法可能类似于:

public static IObservable<T> DeserializeAsObservable<T>(this TextReader reader)
{
    var jsonReader = new JsonTextReader(reader);

    if (!jsonReader.Read() || jsonReader.TokenType != JsonToken.StartArray)
        throw new Exception();

    var serializer = JsonSerializer.Create(null);

    return Observable.Create<T>(o => 
        {
            while (true)
            {
                if (!jsonReader.Read())
                    o.OnError(new Exception());
                if (jsonReader.TokenType == JsonToken.EndArray)
                    break;
                var obj = serializer.Deserialize<T>(jsonReader);
                o.OnNext(obj);
            }
            o.OnCompleted();
            return Disposable.Empty;
        });
}

(显然只有在用更合适的异常类型替换new Exception()之后才使用它。)