2015-01-29 3 views
1

Я использую Json.Net для использования некоторых доступных для поиска потоков.Предотвращение использования JsonTextReader во время десериализации

// reset the input stream, in case it was previously read 
inputStream.Position = 0; 
using (var textReader = new StreamReader(inputStream)) 
{ 
    using (var reader = new JsonTextReader(textReader)) 
    { 
     deserialized = serializer.Deserialize(reader, expectedType); 
    } 
} 

Тем не менее, этот метод «потребляет» поток, то есть первый содержал маркер действует Json удаляется из потока.

Это очень раздражает. И бессмысленная позиция потока предоставляется для подражания потреблению, а «чтение» обычно подразумевает «не изменять».

Конечно, я могу сбросить поток в MemoryStream, чтобы защитить мой драгоценный поток источника, но это огромные накладные расходы, особенно при пробной и ошибке при десериализации.

Если есть способ просто «читать», а не «читать-и-потреблять», спасибо за вашу помощь, я не мог найти документацию об этом (и я надеюсь, что этот пост поможет другим google-решению ^^).

ответ

0

Поток может потребляться после считывания. Решение может состоять в том, чтобы скопировать его в поток памяти или файла, как показано ниже:

MemoryStream ms = new MemoryStream(); 
inputStream.CopyTo(ms); 
ms.Position = 0; 
using (var textReader = new StreamReader(ms)) 
(...) 

Сообщите мне, если он будет работать.

+1

ОП конкретно говорится в вопросе, что он не хотел, чтобы скопировать поток из-за высоких накладных расходов. –

1

JsonTextReader является вперед только читателя, то есть он не может быть установлен обратно в положение, ранее в JSON перечитать часть его, даже если основной поток поддерживает поиск. Однако, как вы сказали, читатель фактически не «потребляет» поток. Если вы установили свойство CloseInput на считывающее устройство на false, чтобы предотвратить его закрытие базового считывателя и потока при его размещении, вы можете поместить поток обратно в начало и открыть новый читатель в том же потоке, чтобы перечитать JSON , Вот короткая программа для демонстрации чтения и тот же поток дважды:

class Program 
{ 
    static void Main(string[] args) 
    { 
     string json = @"{ ""name"": ""foo"", ""size"": ""10"" }"; 
     MemoryStream inputStream = new MemoryStream(Encoding.UTF8.GetBytes(json)); 

     JsonSerializer serializer = new JsonSerializer(); 

     using (var textReader = new StreamReader(inputStream)) 
     { 
      for (int i = 0; i < 2; i++) 
      { 
       inputStream.Position = 0; 

       using (var reader = new JsonTextReader(textReader)) 
       { 
        reader.CloseInput = false; 

        Widget w = serializer.Deserialize<Widget>(reader); 

        Console.WriteLine("Name: " + w.Name); 
        Console.WriteLine("Size: " + w.Size); 
        Console.WriteLine(); 
       } 
      } 
     } 
    } 
} 

class Widget 
{ 
    public string Name { get; set; } 
    public int Size { get; set; } 
} 

Выход:

Name: foo 
Size: 10 

Name: foo 
Size: 10 

Fiddle: https://dotnetfiddle.net/fftZV7

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