我有以下代码用于使用 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/