如何在 BizTalk 管道组件中有效地修改流中的文本?
Posted
技术标签:
【中文标题】如何在 BizTalk 管道组件中有效地修改流中的文本?【英文标题】:How can i modify text in a stream efficiently, in a BizTalk pipeline component? 【发布时间】:2011-06-05 06:41:25 【问题描述】:我有一个包含文本的流,现在我想在该流中编辑一些文本(替换一些值)。
在不中断流的情况下,最有效的方法是什么?
我想在 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()
时,我正在中断流。
有没有更好的方法来做到这一点?
【问题讨论】:
【参考方案1】:对于不可搜索的只读流的简单情况,您可以创建一个包装流,根据需要在Stream.Read
(可能还有Stream.ReadByte
)方法中进行即时替换。但是这些都适用于原始字节,因此您可能还必须考虑流编码。
【讨论】:
您能否详细说明一些代码示例?我没有流媒体经验.. thx【参考方案2】:您在管道组件中使用 Stream 类这一事实并不像您直观地想象的那样使其成为 流式管道组件本身。
最合适的方式是将职责分成两部分:
首先,您创建一个客户System.IO.Stream
类 - 这是一个包装原始传入流并公开流接口的类。在此类中,您将有效地处理调用代码读取的字节。此类不应依赖于 BizTalk,并且您应该能够在 BizTalk 之外为此类创建示例单元测试程序。
对于第一种情况,我建议您浏览到 several articles with source code samples 之一。
其次,管道组件本身,其唯一职责是将传入流替换为您的自定义流的实例。这是一种惯用的模式,您可以在良好的管道组件中找到它。特别是在Execute method 的执行过程中,您不应该读取原始传入流。当Messaging Agent 接管时,读取将自动发生 - 自动。以下 sn-p 应该是Execute
method 的规范源代码,当然,除了用于错误处理的额外代码之外:
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;
看到了吗?在前面的方法中没有任何读取。整个处理过程应在自定义 Stream
类中的 Read
方法的(重复)调用期间发生。
正如我在回复the following question 时所写,我强烈建议您查看Nic Barden 撰写的有关开发流式管道组件的整个系列帖子。
【讨论】:
【参考方案3】:我认为方法是保留一个完成和一个处理缓冲区,然后当您将新内容写入流时,您将其保留在待处理缓冲区中,直到您知道没有其他内容可以替换。 在替换或决定没有什么可以替换之后,将该数据从挂起的缓冲区移动到完成的缓冲区。 read 方法应该只从 done 缓冲区读取,write 应该只写入处理缓冲区,flush 将所有挂起的内容移动到 done。
不关心刷新部分,我正在考虑如何以最好的方式做到这一点,因为我需要编写一个通用字符串替换流。
[edit] 抱歉,回复了一个 2 年前的帖子...[/edit]
【讨论】:
以上是关于如何在 BizTalk 管道组件中有效地修改流中的文本?的主要内容,如果未能解决你的问题,请参考以下文章