只有部分流正在管道组件中写入

时间:2015-05-14 19:25:32

标签: biztalk biztalk-2013 biztalk-pipelines

我正在构建一个可以将图像格式转换为另一种格式的管道组件(例如jpg到png):

using (System.Drawing.Bitmap bmpSource = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(msgReceived.BodyPart.Data))
{
    VirtualStream strConvertedImage = new VirtualStream();

    bmpSource.Save(strConvertedImage, System.Drawing.Imaging.ImageFormat.Png);

    strConvertedImage.Flush();
    strConvertedImage.Position = 0;

    ctxPipeline.ResourceTracker.AddResource(strConvertedImage);
}

msgReceived.BodyPart.Data = strConvertedImage;

我在带有文件适配器的接收管道中使用此组件,并且执行正常,但是当我使用直通发送端口和文件适配器订阅时,写入的文件只是实际图像的一部分。

注意:

我可以在Windows控制台应用程序中使用相同的代码(除了从文件流加载源位图而不是BizTalk消息流),它工作正常,所以这似乎与BizTalk相关。

我认为它与源流有关。

这似乎很奇怪,但如果我检查msgReceived.BodyPart.Data的长度和位置属性,则长度为904678.位置为0.位置保持为0并且即使在加载和保存位图时也不会更改。我希望当我加载位图时,位置会发生变化,除非BitMap.FromStream方法在完成加载后寻找流的开头。

此外,当我将位图作为png保存到我的新流时,新的流长度始终为54789,仅代表图像的第一方。现在,如果我立即将相同的位图对象再次保存到新流,则其大小为1400868,表示整个图像,msgReceived.BodyPart.Data.Position现在为904678,表示已读取整个源流。

以下是一个例子:

using (System.Drawing.Bitmap bmpSource = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(msgReceived.BodyPart.Data))
{
    VirtualStream strConvertedImage = new VirtualStream();
    bmpSource.Save(strConvertedImage, System.Drawing.Imaging.ImageFormat.Png);
    strConvertedImage.Flush();
    strConvertedImage.Position = 0;

    //msgReceived.BodyPart.Data.Position is 0
    //msgReceived.BodyPart.Data.Length is 904678
    //strConvertedImage.Position is 54789 (Only part of image was saved)

    strConvertedImage = new VirtualStream();
    bmpSource.Save(strConvertedImage, System.Drawing.Imaging.ImageFormat.Png);

    //msgReceived.BodyPart.Data.Position is 904678
    //msgReceived.BodyPart.Data.Length is 904678
    //strConvertedImage.Position is 1400868 (full image was saved)

    msgReceived.BodyPart.Data = strConvertedImage;
    ctxPipeline.ResourceTracker.AddResource(strConvertedImage);
}

为什么msgReceived.BodyPart.Data的位置只会在第二次保存时前进?为什么第一次保存尝试只保存部分转换后的图像。我感到困惑!

1 个答案:

答案 0 :(得分:1)

我要避免使用Data属性,除非在最后设置流;每MSDN它克隆数据流,有时会出现意外行为(我已经看到Data属性在某些适配器中为空,即使GetOriginalDataStream()成功返回了流)。请改用GetOriginalDataStream()。我也避免在管道中使用using块 - 虽然我不明白为什么你的例子会出问题,但是很容易错误地处理最终处理原始数据流的流。

例如,

Stream originalStream = msgReceived.BodyPart.GetOriginalDataStream();
originalStream.Seek(0, SeekOrigin.Begin);
VirtualStream vtsConvertedImage = new VirtualStream()
System.Drawing.Bitmap bmpSource = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(originalStream);

bmpSource.Save(vtsConvertedImage, System.Drawing.Imaging.ImageFormat.Png);

vtsConvertedImage.Flush();
vts.ConvertedImage.Seek(0, SeekOrigin.Begin);

msgReceived.BodyPart.Data = vtsConvertedImage;
ctxPipeline.ResourceTracker.AddResource(vtsConvertedImage);
ctxPipeline.ResourceTracker.AddResource(bmpSource);
相关问题