Come posso modificare il testo in un flusso in modo efficiente, in un componente della pipeline BizTalk?

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

Domanda

Ho un flusso che contiene testo, ora voglio modificare un testo (sostituire alcuni valori) in quel flusso.

Qual è il modo più efficace per fare questo, quindi senza rompere il flusso? Voglio usare questo in un componente della pipeline personalizzato per 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;
}

Questo è il codice, ma come potete vedere sto rompendo il flusso quando faccio sr.ReadToEnd().

C'è un modo beter per fare questo?

Nessuna soluzione corretta

Altri suggerimenti

Il fatto che si sta utilizzando classi stream nel tuo componente della pipeline non fanno un Streaming componente della pipeline per-sé come hai intuitivamente chiesti.

Il modo più appropriato è quello di dividere le responsabilità in due componenti:

  • In primo luogo, si crea una classe cliente System.IO.Stream - che è una classe che avvolge il flusso in entrata originale ed espone un'interfaccia in streaming. In questa classe, si sarebbe effettivamente elaborare i byte come sono letti dal codice chiamante. Questa classe dovrebbe avere alcuna dipendenza sopra BizTalk e si dovrebbe essere in grado di creare un programma di unità di test di esempio per questa classe al di fuori BizTalk.

Per il primo caso, vi consiglio si passa a uno dei diversi articoli con esempi di codice sorgente .

  • In secondo luogo, il componente della pipeline stessa, la cui responsabilità unica è quello di sostituire il flusso in entrata con un'istanza del flusso personalizzato. Si tratta di un modello idiomatica che troverete in buone componenti della pipeline. In particolare, durante l'esecuzione della metodo Execute , non si dovrebbe leggere il flusso in entrata originale . La lettura avverrà - automagicamente - da sola quando la Messaging Agent prende il sopravvento.

Il seguente frammento deve essere il codice sorgente canonica per una Executemethod, salvo codice aggiuntivo per la gestione degli errori, naturalmente:

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

Vedi? No lettura di sorta nel metodo precedente. L'intero processo dovrebbe accadere durante le chiamate (ripetuti,) del metodo Read nella tua classe Stream personalizzato.

Come ho scritto nella mia risposta a alla seguente domanda , vi incoraggio vivamente di controllare l'intera serie di post Nic Barden ha fatto di sviluppare Streaming Pipeline Components.

Per il semplice caso di mancato seekable flusso di sola lettura, è possibile creare un flusso di wrapper che fa le sostituisce on-the-fly, se necessario nel metodo (ed eventualmente il Stream.Read) Stream.ReadByte. Tuttavia questi lavori con byte prime, quindi potrebbe essere necessario conto per il flusso di codifica troppo.

Penso che il modo sarebbe quello di mantenere un fatto e un buffer di elaborazione, quindi è l'arrivo di nuovi contenuti scritti per il vostro flusso di tenerlo nel buffer in attesa finché non si sa non c'è niente di più per sostituire. Dopo la sostituzione o di decidere non c'è niente di sostituire mossa che i dati dal attesa nel buffer di fatto. Il metodo di lettura deve solo leggere dal buffer fatto, la scrittura deve scrivere solo per il buffer di elaborazione e si muove a filo tutto il pendente per fare.

Non shure circa la parte di lavaggio, sto a pensare come farlo nel migliore dei modi, come ho bisogno di scrivere un flusso stringa sostituto generico.

[modifica] Ci dispiace, rispose una di 2 anni post ... [/ modifica]

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top