2015-06-29 1 views
1

Я следующий код для чтения потока с помощью JsonTextReader и JObject.Load:JsonTextReader.Read() и JObject.Load (jsonTextReader) механизм

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. Но заглядывая в JObject.Load (jsonTextReader) с помощью Resharper показывает, что несколько раз, когда 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#), разве это не эквивалентно тому, что Read() вызывается несколько раз на jsonTextReader внутри цикла while?

Дело в том, что код работает. Поэтому приведенное выше объяснение неверно. Я просто не знаю, какая часть объяснений неверна. Может кто-нибудь объяснить, как поток считывается токеном с помощью токена, используя JSonTextReader.Read() и JObject.Load().

ответ

1

Я не знаю, где это задокументировано, но это поведение «от одного» последовательно работает с JSON.NET при чтении. Различные внутренние функции, которые потребляют JsonReader, ожидают, что их первый символ будет потреблять, чтобы быть уже прочитанным и быть доступным для проверки, но когда они заканчивают, они не читаются в следующем символе после их последнего. Это помогает при написании рекурсивных обработчиков сериализации: вы можете увидеть первый символ и затем принять решение от того, какой метод передать поток.

В вашем примере, после вызова JObject.Load, jsonTextReader.TokenType будет JsonToken.EndObject.

Смежные вопросы