如何使用JsonTextReader两次



我得到了一个json数据流,其中包含一个名为"type"的字段。此类型字段描述需要在运行时创建的对象的类型。看起来我无法使用JsonTextReader两次,也无法将文本阅读器重置为开头。

using (var streamReader = new StreamReader(stream, Encoding))
using (var jsonTextReader = new JsonTextReader(streamReader))
{
    JToken token = JObject.Load(jsonTextReader);
    var type = (string) token.SelectToken("type");
    var modelType = Type.GetType("Project." + type + ", Project");
    // Fails here
    var obj = serializer.Deserialize(jsonTextReader, modelType);
}

我收到这个错误消息。反序列化对象时出现意外标记:EndObject。

您可以从JToken创建JsonReader。

JsonReader reader = token.CreateReader();

若要将读取器重置为初始,请将基础流的Position属性设置为0。

streamReader.BaseStream.Position = 0;

编辑:虽然这将重置底层流,但根据定义,jsonTextReader是仅向前,这意味着它的行号和位置是只读的。要使其工作,您必须重置streamReader位置,然后将其输入到新的JsonTextReader对象中。

因此,不幸的是,Phil,由于JsonTextReader只是向前的,因此无法阅读两次。

参考:http://james.newtonking.com/projects/json/help/html/T_Newtonsoft_Json_JsonTextReader.htm"表示提供对序列化Json数据的快速、非缓存、仅前向访问的读取器。"

根据James Newton King的建议,我在博客中介绍了以节省内存的格式使用JsonTextReader,避免使用大型对象堆等。您可以利用它和提供的代码多次读取JSON,而无需担心JsonTextReader的底层实现。

欢迎评论和反馈。

我做了更多的测试,发现以下内容有效。

  1. 设置JsonTextReader.CloseInput = false
  2. 销毁JsonTextReader(通过关闭using语句)
  3. 设置StreamReader.BaseStream.Position = 0
  4. 新建JsonTextReader

它看起来像这样:

using (var streamReader = new StreamReader(stream, encoding))
{
    Type modelType = null;
    using (var jsonTextReader = new JsonTextReader(streamReader))
    {
        jsonTextReader.CloseInput = false;
        JToken token = JObject.Load(jsonTextReader);
        string type = (string)token.SelectToken("type");
        modelType = Type.GetType("Project." + type + ", Project");
    }
    streamReader.BaseStream.Position = 0;
    using (var jsonTextReader = new JsonTextReader(streamReader))
    {
        var obj = serializer.Deserialize(jsonTextReader, modelType);
    }
}

最新更新