Question

J'ai un flux qui contient du texte, maintenant je veux modifier un texte (remplacer certaines valeurs) dans ce courant.

Quelle est la façon la plus efficace de le faire, sans casser le flux? Je veux l'utiliser dans un composant de pipeline personnalisé pour 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;
}

Ceci est le code, mais comme vous pouvez le voir, je suis briser le flux quand je fais sr.ReadToEnd().

Y at-il un moyen Beter de le faire?

Pas de solution correcte

Autres conseils

Le fait que vous utilisez des classes de flux dans votre composant de pipeline ne fait pas flux de composants de pipeline par-soi que vous avez intuitivement demandé.

La façon la plus appropriée est de diviser les composantes en deux responsabilités:

  • Tout d'abord, vous créez une classe System.IO.Stream client - qui est une classe qui enveloppe le flux entrant d'origine et expose une interface de streaming. Dans cette classe, vous traiter efficacement les octets comme ils sont lus par le code d'appel. Cette classe ne devrait avoir aucune dépendance sur BizTalk et vous devriez être en mesure de créer un programme de test unitaire échantillon pour cette classe en dehors de BizTalk.

Pour le premier cas, je vous recommande de parcourir à l'un des plusieurs articles avec des exemples de code source .

  • En second lieu, le composant de pipeline lui-même, dont la seule responsabilité est de remplacer le flux entrant avec une instance de votre flux personnalisé. Ceci est un modèle idiomatiques que vous trouverez dans les composants de bonne pipeline. En particulier, lors de l'exécution du Exécuter méthode , vous ne devriez pas lire le flux entrant d'origine . La lecture se produira - automagiquement - par lui-même lorsque le Messaging Agent prend le relais.

L'extrait suivant doit être le code source canonique pour un Executemethod, sauf code supplémentaire pour la gestion des erreurs, bien sûr:

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

Voir? Aucune lecture que ce soit dans le procédé précédent. Le traitement complet devrait se produire pendant les appels (repated) de la méthode Read dans votre classe Stream personnalisée.

Comme je l'ai écrit dans ma réponse à question suivante, je vous encourage fortement à consulter la série de messages Nic Barden a fait sur le développement de composants pipeline en streaming.

Pour le cas simple de flux en lecture seule non-adressable, vous pouvez créer un flux d'emballage qui ne les remplace à la volée, au besoin dans la méthode Stream.Read (et peut-être le Stream.ReadByte). Cependant, ces travaux avec des octets premières, donc vous pouvez avoir à compte pour le flux encodant aussi.

Je pense que la façon serait de garder un fait et un tampon de traitement, alors vous lorsque vous obtenez le nouveau contenu écrit à votre flux que vous le garder dans la mémoire tampon en attente jusqu'à ce que vous savez qu'il n'y a plus rien à remplacer. Après avoir remplacé ou il n'y a rien de décider de remplacer déplacer que les données de l'attente dans le tampon fait. Le procédé de lecture ne doit lire à partir du tampon fini, l'écriture ne doit écrire dans le tampon de traitement et se déplace à chasse d'eau tout en attendant le fait de.

FCKeditor de la partie de chasse, je me surprends à penser comment faire de la meilleure façon que je dois écrire un flux de succédané de chaîne générique.

[modifier] désolé, répondit un poste vieux de 2 ans ... [/ edit]

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top