Как я могу изменить текст в потоке эффективно, в компоненте трубопровода 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().

Есть ли способ сделать этот вопрос?

Нет правильного решения

Другие советы

Тот факт, что вы используете классы потоков в вашем компоненте трубопровода, не делают его Потоковый компонент трубопровода Per-SE Как у вас интуитивно задается вопросом.

Наиболее подходящим способом - разделить разрыв на два компонента:

  • Во-первых, вы создаете клиента System.IO.Stream Класс - это класс, который обернут оригинальный входящий поток и обнажает потоковый интерфейс. В этом классе вы эффективно обрабатывали байты Как они читаются по вызовому коду. Этот класс не должен иметь зависимость от BizTalk, и вы сможете создать пробую программу тестирования модулей для этого класса за пределами BizTalk.

Для первого случая я рекомендую вам просматривать один из несколько статей с образцами исходного кода.

  • Во-вторых, сам компонент трубопровода, единственную отзывчивость которого состоит в том, чтобы заменить входящий поток с помощью экземпляра вашего пользовательского потока. Это идиоматический шаблон, который вы найдете в хороших компонентах трубопровода. В частности, во время выполнения Выполнить метод, Вы не должны читать оригинальный входящий поток. Отказ Чтение произойдет - автоматически - сам по себе когда Агент обмена сообщениями берет на себя.

Следующий фрагмент должен быть канонический исходный код для 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 сорт.

Как я писал в своем ответе на следующий вопрос, Я настоятельно рекомендую вам проверить всю серию постов Ник Барден сделал о разработке потоковых трубопроводных компонентов.

Для простого случая неисправночного потока только для чтения вы можете создать поток обертки, который делает заменяет на лету, по мере необходимости в Stream.Read (и, возможно, Stream.ReadByte) метод. Однако эти работы с необработанными байтами, поэтому вам, возможно, придется объяснить кодировку потока тоже.

Я думаю, что, как можно было бы сделать сделать сделано и буфер обработки, затем вы, когда вы получите новый контент, записанный на ваш поток, вы сохраняете его в ожидающем буфере, пока не знаете, что нет ничего, чтобы заменить. После замены или решить, что нечего заменить, переместите эти данные от ожидания до выполненного буфера. Способ чтения должен прочитать только из готового буфера, запись должна записывать только на буфер обработки и промывать все ожидающие для выполнения.

Не вытекайте о промывочной части, я думаю, как это сделать наилучшим образом, так как мне нужно написать общий String Striender Stream.

править] Извините, ответил 2 года пост ... [/ edit

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top