2011-01-07 6 views
5

У меня есть поток, содержащий текст, теперь я хочу отредактировать некоторый текст (замените некоторые значения) в этом потоке.Как можно эффективно редактировать текст в потоке в компоненте конвейера BizTalk?

Каков наиболее эффективный способ сделать это, не нарушая поток? Я хочу использовать это в пользовательском компоненте конвейера для 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().

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

ответ

2

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

+0

Можете ли вы разработать некоторые примеры кода? У меня нет опыта потоковой передачи. Thx –

4

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

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

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

Для первого случая, я рекомендую вам перейти на один из several articleswith source code samples.

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

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

Как я уже писал в своем ответе the following question, я настоятельно рекомендую вам ознакомиться со всей серией сообщений Nic Barden о разработке компонентов потокового трубопровода.

0

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

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

[править] Извините, ответила 2-летняя статья ...