BizTalkパイプラインコンポーネントで、ストリームのテキストを効率的に変更するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/4625819

質問

テキストを含むストリームがありますが、そのストリームでテキスト(いくつかの値を置き換える)を編集したいと思います。

これを行うための最も効率的な方法は何ですか?これをカスタムパイプラインコンポーネントで使用したい BizTalk.

public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg)
{
    string msg = "";
    using (VirtualStream virtualStream = new VirtualStream(pInMsg.BodyPart.GetOriginalDataStream()))
    {
        using(StreamReader sr = new StreamReader(VirtualStream))
        {
            msg = sr.ReadToEnd();
        }

        // modify string here
        msg = msg.replace("\r\n","");

        while (msg.Contains(" <"))
           msg = msg.Replace(" <", "<");

        VirtualStream outStream = new VirtualStream();
        StreamWriter sw = new StreamWriter(outStream, Encoding.Default);
        sw.Write(msg);
        sw.Flush();
        outStream.Seek(0, SeekOrigin.Begin);

        pInMsg.BodyPart.Data = outStream;
        pContext.ResourceTracker.AddResource(outStream);
    }

    return pInMsg;
}

これはコードですが、あなたが見ることができるように、私がするとき、私はストリームを壊しています sr.ReadToEnd().

これを行うためのベターの方法はありますか?

正しい解決策はありません

他のヒント

パイプラインコンポーネントでストリームクラスを使用しているという事実は、 STERING PIPELINEコンポーネントPER-SE あなたが直感的に疑問に思ったように。

最も適切な方法は、応答性を2つのコンポーネントに分割することです。

  • まず、顧客を作成します System.IO.Stream クラス - これは、元の着信ストリームをラップし、ストリーミングインターフェイスを公開するクラスです。このクラスでは、バイトを効果的に処理します 彼らが読まれると 呼び出しコードによって。このクラスはBizTalkに依存してはならず、BizTalk以外のこのクラスのサンプルユニットテストプログラムを作成できるはずです。

最初のケースでは、そのうちの1つを閲覧することをお勧めします いくつかの記事 ソースコードサンプル付き.

  • 第二に、パイプラインコンポーネント自体。その唯一の応答性は、着信ストリームをカスタムストリームのインスタンスに置き換えることです。これは、優れたパイプラインコンポーネントにある慣用パターンです。特に、の実行中 メソッドを実行します, 元の着信ストリームを読んではいけません. 。読書が起こります - 自動的に - それ自体が メッセージングエージェント 奪い取る。

次のスニペットは必要です 正規ソースコード のために Executeもちろん、エラー処理のための追加コードを除いて、もちろん:

IBaseMessage IComponent.Execute(IPipelineContext pContext, IBaseMessage pInMsg)
{
   // assign a new CustomStream to the incoming message

    System.IO.Stream stream = pInMsg.BodyPart.GetOriginalDataStream();
    System.IO.Stream customStream = new CustomStream(stream);

    // return the message for downstream pipeline components (further down in the pipeline)

    pInMsg.BodyPart.Data = customStream;
    pContext.ResourceTracker.AddResource(customStream);

    return pInMsg;
}

見る?前の方法ではまったく読み物はありません。処理全体は、 Read カスタムの方法 Stream クラス。

私が応答して書いたように 次の質問, 、一連の投稿全体をチェックすることを強くお勧めします Nic Barden ストリーミングパイプラインコンポーネントの開発について説明しました。

選択不可の読み取り専用ストリームの単純なケースの場合、必要に応じてオンザフライを交換するラッパーストリームを作成できます。 Stream.Read (そしておそらく Stream.ReadByte) 方法。ただし、これらは生のバイトで動作するため、ストリームエンコードも考慮する必要がある場合があります。

完了と処理バッファーを維持する方法だと思います。そして、あなたがあなたのストリームに新しいコンテンツを書き込んだとき、あなたはそれを保留中のバッファに保持しておきます。そのデータを置き換えたり決定した後、そのデータを保留中のバッファーに移動することは何もありません。読み取りメソッドは、完了バッファーからのみ読み取ります。書き込みは処理バッファーにのみ書き込み、フラッシュが行われるまでのすべての保留中の動きを行う必要があります。

フラッシングパートについてshureするのではなく、一般的な文字列置換型ストリームを書く必要があるので、私はこれを最善の方法で行う方法を自分自身に考えています。

編集]申し訳ありませんが、2年前の投稿に答えました... [/編集

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top