Pregunta

Tengo 3 TextReaders - una combinación de StreamReaders y StringReaders. Conceptualmente, la concatenación de ellos es un documento de texto.

Quiero llamar a un método (que no están bajo mi control) que toma un solo TextReader. ¿Hay alguna manera integrada o fácil hacer una TextReader concatenación de múltiples TextReaders?

(I podría escribir mi propia subclase TextReader, pero parece que una buena cantidad de trabajo. En ese caso, yo acababa de escribir a todos a un archivo temporal y luego abrirlo con un solo StreamReader.)

¿Hay una solución fácil a este que me falta?

¿Fue útil?

Solución

Me acaba de lanzar esto juntos, por lo que no es super-resistente (sin control de errores, etc) pero el caso de prueba básica obras.

Funciona mediante la creación de un método de extensión para TextReader de que tienen un segundo, y devuelve una nueva clase TextReader el que llama internamente Read() en la primera hasta que se agote, y luego comienza a llamar Read()on la segunda. Puede encadenar este indefinidamente.

Para proporcionar una implementación completa de TextReader sólo tiene que poner en práctica Read(), Peek(), Close() y Dispose(). Todos los otros métodos se basan en Read() aplicación específica para el trabajo. Por lo tanto la creación de su propia TextReader realmente no es tan malo, como se puede ver a continuación.

Esto también alivia los problemas de rendimiento, ya que estamos simplemente envolviendo la TextReaders existentes y en realidad no los invoca para realizar la concatenación.

class Program
{
    static void Main(string[] args)
    {
        StringReader first = new StringReader("hello ");
        StringReader second = new StringReader("world");
        StringReader third = new StringReader("!");

        using (var allOfThem = first.Concat(second).Concat(third))
        {
            //writes "hello world!"
            Console.WriteLine(allOfThem.ReadToEnd());
        }
        Console.Read();
    }
}

public static class Extensions
{
    public static TextReader Concat(this TextReader first, TextReader second)
    {
        return new ChainedTextReader(first, second);
    }

    private class ChainedTextReader : TextReader
    {
        private TextReader first;
        private TextReader second;
        private bool readFirst = true;

        public ChainedTextReader(TextReader first, TextReader second)
        {
            this.first = first;
            this.second = second;
        }

        public override int Peek()
        {
            if (readFirst)
            {
                return first.Peek();
            }
            else
            {
                return second.Peek();
            }
        }

        public override int Read()
        {
            if (readFirst)
            {
                int value = first.Read();
                if (value == -1)
                {
                    readFirst = false;
                }
                else
                {
                    return value;
                }
            }
            return second.Read();
        }

        public override void Close()
        {
            first.Close();
            second.Close();
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            if (disposing)
            {
                first.Dispose();
                second.Dispose();
            }
        }
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top