我有3个Textreaders - 流程阅读器和弦线阅读器的组合。从概念上讲,它们的串联是一个文本文档。

我想调用一个方法(不在我的控制之下),该方法需要单个Textreader。是否有任何内置或简便的方法来制作来自多个Textreaders的串联Textreader?

(一世 可以 写我自己的Textreader子类,但看起来像相当多的工作。在这种情况下,我只将它们全部写入临时文件,然后用单个流读程序打开它。)

我缺少一个简单的解决方案吗?

有帮助吗?

解决方案

我只是把它们扔了在一起,所以它不是超级努力(没有错误处理等),而是基本的测试用例可行。

它通过为扩展方法创建用于 TextReader花了一秒 Read() 在第一个直到用完为止,然后开始打电话 Read()第二。您可以无限期地链接。

提供完整的实施 TextReader 您只需要实施 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();
            }
        }
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top