c# - JsonTextReader.Read() 和 JObject.Load(jsonTextReader) 机制

标签 c# token streamreader json reference-type

我有以下代码用于使用 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 指针是否向前移动了两次或多次(导致 token 丢失):一次在 jsonTextReader.Read() 中,一次或多次在 JObject.Load(jsonTextReader) 中?我找不到解释有关 JsonTextRead.Read() 或 JObject.Load 的详细信息的文档。但使用 Resharper 查看 JObject.Load(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() 逐个 token 地读取流。

最佳答案

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

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

关于c# - JsonTextReader.Read() 和 JObject.Load(jsonTextReader) 机制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31126593/

相关文章:

c# - 我应该将 StreamReader/Writer 与 NetworkStream 一起用于 C# 服务器/客户端吗?

.net - 动态创建 csv 文件作为 StreamReader

c# - 线程有等待语句吗?

c# - 如何以编程方式删除受信任的根证书颁发机构中的证书?

java - Firebase 消息不起作用

iphone - 将设备 token 发送到服务器

c# - StreamReader.ReadLine 将陷入无限循环

C# 将对象转换为十进制

c# - 在 TDD 中创建测试数据的最佳位置在哪里?

flutter - 用于 Flutter 中 PayPal 支付的 Braintree 集成