JsonTextReader.Read() and JObject.Load(jsonTextReader) mecha

本文关键字:jsonTextReader mecha Load and Read JsonTextReader JObject | 更新日期: 2023-09-27 18:00:20

我有以下代码用于使用JsonTextReader和JObject.Load:读取流

private void ProcessStream(Stream stream)
{
    stream.Position = 0;
    using (StreamReader streamReader = new StreamReader(stream))
    {
        using (JsonTextReader jsonTextReader = new JsonTextReader(streamReader))
        {
            while (jsonTextReader.Read())
            {
                if (jsonTextReader.TokenType == JsonToken.StartObject)
                {
                    JObject jObject = JObject.Load(jsonTextReader);
                    /* Manipulate jObject */
                }
            }
        }
    }
}

我的问题是,jsonTextReader指针不是向前移动了两次或两次以上(导致标记丢失):一次在jsonTextReader.Read(),一次或多次在JObject.Load(jsonTextReader)?我找不到解释JsonTextRead.Read()或JObject.Load的详细信息的文档。但使用Resharper查看JObject.Lload(jsonTextReader)可以发现,有多次调用jsonTextReader.Read():

public new static JObject Load(JsonReader reader)
{
    ...
    while (reader.TokenType == JsonToken.Comment)
    {
        reader.Read();
    }
    ...
    JObject o = new JObject();
    o.SetLineInfo(reader as IJsonLineInfo);
    o.ReadTokenFrom(reader);
    return o;
}
internal void ReadTokenFrom(JsonReader reader)
{
    ...
    if (!reader.Read())
        throw JsonReaderException.Create(reader, "Error reading {0} from JsonReader.".FormatWith(CultureInfo.InvariantCulture, GetType().Name));
    ReadContentFrom(reader);
    ...
}
internal void ReadContentFrom(JsonReader r)
{
    ...
    do{
    } while (r.Read());
}

是否通过值将jsonTextReader传递给JObject.Load()?如果不是,并且它是通过引用Load()传递的(这通常是C#类对象的情况),这不等于在while循环中对jsonTextReader多次调用Read()吗?

事实是,代码似乎是有效的。所以上面的解释是不正确的。我只是不确定解释的哪一部分是错误的。有人能解释一下如何使用JSonTextReader.read()和JObject.Load()来逐个标记地读取流吗?

JsonTextReader.Read() and JObject.Load(jsonTextReader) mecha

我不知道它具体记录在哪里,但这种"逐个"的行为始终是JSON.NET在阅读方面的工作方式。使用JsonReader的各种内部函数都希望它们要使用的第一个符号已经被读取并可供检查,但当它们完成时,它们不会读取最后一个符号之后的下一个符号。在编写递归序列化处理程序时,它会有所帮助:您可以看到第一个符号,然后根据它来决定将流传递给哪个方法。

在您的示例中,在调用JObject.Load之后,jsonTextReader.TokenType将为JsonToken.EndObject.