Frage

Ich habe einen Stream, der Text enthält, jetzt habe ich bearbeiten möchten einen Text (einige Werte ersetzen) in diesem Strom.

Was ist der effizienteste Weg, dies zu tun, also ohne den Strom zu brechen? Ich möchte dies in einer für BizTalk benutzerdefinierte Pipeline-Komponente verwenden.

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

Dies ist der Code, aber wie man sehen kann ich den Strom breche, wenn ich sr.ReadToEnd() tun.

Sie haben einen beter Weg, dies zu tun?

Keine korrekte Lösung

Andere Tipps

Die Tatsache, dass Sie Stream-Klassen in Ihrer Pipeline-Komponente verwenden, nicht macht es zu einer Streaming-Pipeline-Komponente per se , wie Sie intuitiv gefragt haben.

Der am besten geeignete Weg, um die Verantwortungen in zwei Komponenten aufgeteilt:

  • Zuerst Sie einen Kunden System.IO.Stream Klasse erstellen - das ist eine Klasse, die den ursprünglichen eingehenden Strom wickelt und stellt eine Streaming-Schnittstelle. In dieser Klasse würden Sie effektiv das Bytes verarbeiten, wie sie durch den anrufenden Code gelesen werden. Diese Klasse sollte keine Abhängigkeit über BizTalk haben und Sie sollten eine Probeneinheit-Testprogramm für diese Klasse außerhalb BizTalk erstellen können.

Für den ersten Fall, empfehle ich Ihnen, einem der durchsuchen mehrere Artikel mit Quellcode Proben .

  • Zweitens ist die Pipeline-Komponente selbst, deren alleinige Verantwortung ist, den ankommenden Strom mit einer Instanz des benutzerdefinierten Strom zu ersetzen. Dies ist ein idiomatisches Muster, das Sie in dem guten Pipeline-Komponenten finden. Insbesondere während der Ausführung der Execute-Methode , Sie sollten nicht den ursprünglichen eingehenden Strom . Die Lesung wird passieren - automagically - selbst wenn die Messaging Agent übernimmt.

Das folgende Snippet sollte die kanonische Quellcode für ein Executemethod, abgesehen von zusätzlichem Code für die Fehlerbehandlung, natürlich:

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

Sehen Sie? Kein Lesen überhaupt in dem vorhergehenden Verfahren. Die gesamte Verarbeitung während der (repated) Anrufe der Read Methode in Ihrer benutzerdefinierten Stream Klasse passieren sollte.

Wie ich schrieb in meiner Antwort auf die folgende Frage , ich empfehlen Ihnen dringend, die ganze Reihe von Stellen zu überprüfen, Nic Barden über die Entwicklung von Streaming-Pipeline-Komponenten getan hat.

Für den einfachen Fall von Nicht-seekable Read-Only-Stream können Sie einen Wrapper-Stream erstellen, die ersetzt on-the-fly tut, wie in der Stream.Read (und möglicherweise die Stream.ReadByte) Methode benötigt. Doch diese Arbeit mit rohem Bytes, so dass Sie zu Konto für den Strom zu kodieren können.

ich glaube, die Art und Weise ein getan und einen Verarbeitungspuffer zu halten wäre, dann sind Sie, wenn Sie neue Inhalte auf Ihren Stream geschrieben bekommen Sie es in der anstehenden Puffer halten, bis Sie wissen, dass es nichts mehr zu ersetzen. Nach dem Austausch oder die Entscheidung, es gibt nichts bewegen, dass die Daten aus dem anstehenden zum done Puffer zu ersetzen. Die Lesemethode sollte nur aus dem done Puffer gelesen, soll die Schreib nur auf die Verarbeitungspuffer schreiben und bündig bewegen alle anhängig gemacht.

Nicht shure über die Spülung Teil, denke ich mich, wie dies in der besten Art und Weise zu tun, wie ich einen Stream generischen String replacer schreiben muß.

[Bearbeiten] sorry, antwortete ein 2 Jahre alt Beitrag ... [/ edit]

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top