C# 如何将多个文本阅读器串在一起?

C# 如何将多个文本阅读器串在一起?,c#,concatenation,streamreader,stringreader,textreader,C#,Concatenation,Streamreader,Stringreader,Textreader,我有3个文本阅读器——StreamReaders和StringReaders的组合。从概念上讲,它们的连接是单个文本文档 我想调用一个方法(不在我的控制之下),它只接受一个文本阅读器。有什么内置的或简单的方法可以从多个文本阅读器中创建一个串联文本阅读器吗 (我可以编写自己的TextReader子类,但看起来工作量相当大。在这种情况下,我只需将它们全部写入一个临时文件,然后用一个StreamReader打开即可。) 有没有一个简单的解决方案是我缺少的?我只是把它放在一起,所以它不是超级健壮的(没有

我有3个文本阅读器——StreamReaders和StringReaders的组合。从概念上讲,它们的连接是单个文本文档

我想调用一个方法(不在我的控制之下),它只接受一个文本阅读器。有什么内置的或简单的方法可以从多个文本阅读器中创建一个串联文本阅读器吗

(我可以编写自己的TextReader子类,但看起来工作量相当大。在这种情况下,我只需将它们全部写入一个临时文件,然后用一个StreamReader打开即可。)


有没有一个简单的解决方案是我缺少的?

我只是把它放在一起,所以它不是超级健壮的(没有错误处理等),但是基本的测试用例可以工作

它的工作原理是为
TextReader
创建一个扩展方法,该方法需要一秒钟的时间,然后返回一个新的TextReader类,该类在第一个类中内部调用
Read()
,直到用完为止,然后在第二个类中开始调用
Read()
。您可以无限期地将其链接

要提供
文本阅读器
的完整实现,只需实现
Read()
Peek()
Close()
Dispose()
。所有其他方法都依赖于特定的实现
Read()
。因此,创建自己的
TextReader
并没有那么糟糕,正如您在下面看到的

这也减轻了任何性能问题,因为我们只是包装现有的文本阅读器,而不是实际调用它们来执行连接

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();
            }
        }
    }
}

哦,这很聪明:只处理2,并使用扩展方法来链接它们。