質問

TexTreadersは3人います。ストリームリーダーとStringReaderの組み合わせです。概念的には、それらの連結は単一のテキストドキュメントです。

単一のTexTreaderを使用するメソッド(私の管理下にはない)を呼び出したいと思います。複数のテキストリーダーから連結したテキストリーダーを作成するための組み込みや簡単な方法はありますか?

(私 たぶん......だろう 私自身のテキストリーダーのサブクラスを書いてくださいが、それはかなりの量の作業のように見えます。その場合、それらをすべてTEMPファイルに書き出してから、単一のStreamReaderで開きます。)

私が欠けているこれに対する簡単な解決策はありますか?

役に立ちましたか?

解決

私はこれを一緒に投げただけなので、それは超堅実ではありません(エラー処理などはありません)が、基本的なテストケースは機能します。

拡張メソッドを作成することで機能します TextReader1秒かかり、内部的に呼び出す新しいTexTreaderクラスを返す Read() 最初になくなるまで、それがなくなってから呼び出しを開始します Read()2番目。これを無期限にチェーンすることができます。

の完全な実装を提供する 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