2015-07-27 3 views
1

Как я обрабатываю XML, как определить, сколько данных я уже обработал, будь то в байтах или в символах? Если базовый поток был FileStream, это было бы легко. Как я могу сделать это с базовым NetworkStream?Как определить, сколько данных было прочитано XmlTextReader?

Очень важны соображения производительности и памяти.

NetworkStream reportStream = GetStream(); 
using (var bufferStream = new BufferedStream(reportStream)) 
{ 
    using (var xmlTextReader = new XmlTextReader(bufferStream)) 
    { 
    while (xmlTextReader.Read()) 
    { 
     // TODO check how much data have been read already 
     // bufferStream.Position and bufferStream.Length don't work 
     // because NetworkStream doesn't support them by design 

     // process XML data 
    } 
    } 
} 
+1

Оберните поток в другой и посчитайте? –

+0

'Read()': считывает следующий узел из потока. –

+0

Спасибо, @AlexeiLevenkov –

ответ

2

Как было предложено @AlexeiLevenkov, я применил простую обертку потока для моего варианта использования.

public class CountingStream : Stream 
{ 
    private Stream _stream; 
    private long _totalBytesRead; 
    private long _totalBytesWritten; 

    public CountingStream(Stream stream) 
    { 
     _stream = stream; 
     _totalBytesRead = 0; 
     _totalBytesWritten = 0; 
    } 

    public long TotalBytesRead { get { return _totalBytesRead; } } 
    public long TotalBytesWritten { get { return _totalBytesWritten; } } 

    public override void Flush() 
    { 
     _stream.Flush(); 
    } 

    public override long Seek(long offset, SeekOrigin origin) 
    { 
     return _stream.Seek(offset, origin); 
    } 

    public override void SetLength(long value) 
    { 
     _stream.SetLength(value); 
    } 

    public override int Read(byte[] buffer, int offset, int count) 
    { 
     int bytesRead = _stream.Read(buffer, offset, count); 
     _totalBytesRead += bytesRead; 
     return bytesRead; 
    } 

    public override void Write(byte[] buffer, int offset, int count) 
    { 
     _totalBytesWritten += count; 
     _stream.Write(buffer, offset, count); 
    } 

    public override bool CanRead 
    { 
     get { return _stream.CanRead; } 
    } 

    public override bool CanSeek 
    { 
     get { return _stream.CanSeek; } 
    } 

    public override bool CanWrite 
    { 
     get { return _stream.CanWrite; } 
    } 

    public override long Length 
    { 
     get { return _stream.Length; } 
    } 

    public override long Position 
    { 
     get { return _stream.Position; } 
     set { _stream.Position = value; } 
    } 

    protected override void Dispose(bool disposing) 
    { 
     try 
     { 
      if (!disposing) 
       return; 
      if (_stream == null) 
       return; 

      try 
      { 
       Flush(); 
      } 
      finally 
      { 
       _stream.Close(); 
      } 
     } 
     finally 
     { 
      _stream = null; 
      base.Dispose(disposing); 
     } 
    } 
} 
+2

Если производительность является проблемой, вы должны рассмотреть возможность переопределения * всех * виртуальных методов 'Stream' для вызова тех же методов базового экземпляра. Многие потоки предоставляют реализации с улучшением производительности, которые, например, превосходят по умолчанию реализацию ReadByte. –

+0

хорошо пункт. спасибо, я посмотрю. –

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