【问题标题】:How can I decompress a gzip file in a custom pipeline如何在自定义管道中解压缩 gzip 文件
【发布时间】:2017-02-11 04:10:24
【问题描述】:

我尝试创建一个自定义 BizTalk 2013 R2(接收或发送)管道,该管道可以将包含一些 txt 文件的 xxx.GZ 文件解压缩到发送端口。

这是我迄今为止尝试过的:

PS。我使用了 .Net 的 IO GZip 类。

  1. 创建了一个 BTS 应用,配置了接收位置和发送端口。

  2. 接收位置使用我创建的自定义管道,这是我尝试的自定义管道的代码:

        public void Disassemble(IPipelineContext pc, IBaseMessage inmsg)
        {
            IBaseMessagePart bodyPart = inmsg.BodyPart;
    
            if (bodyPart != null)
            {
                Stream originalStream = bodyPart.GetOriginalDataStream();
    
               if (originalStream != null)
                {                     
                    using (GZipStream gZipInputStream = new GZipStream(new MemoryStream(originalStream.ReadByte()), CompressionMode.Decompress))
                    {    
                        MemoryStream memStream = new MemoryStream();
                        byte[] buffer = new Byte[1024];
    
                        int bytesRead = 1024;
                        while (bytesRead != 0)
                        {
                            bytesRead = gZipInputStream.Read(buffer, 0, buffer.Length);
    
                            gZipInputStream.CopyTo(buffer, 0);
                            memStream.Write(buffer, 0, bytesRead);
                        }
    
                        IBaseMessage outMessage;
                        outMessage = pc.GetMessageFactory().CreateMessage();
                        outMessage.AddPart("Body", pc.GetMessageFactory().CreateMessagePart(), true);
                        memStream.Position = 0;
                        outMessage.BodyPart.Data = memStream;
    
                        outMessage.Context = PipelineUtil.CloneMessageContext(inmsg.Context);
    
                        _msgs.Enqueue(outMessage);
    
                        }
                    }   
            }
    
        }
    

此代码似乎无法按我的意愿工作。只需发送 GZ 文件而不将其解压缩到发送端口。我在接收位置端口中使用实现的管道。以下是它的工作原理:当 BizTalk 在其接收位置接收到 GZ 打包文件时,它只是将文件发送到订阅此接收位置的发送端口。管道似乎对 GZ 流没有任何作用。它应该做的是将GZ文件解压并将所有解压文件发送到发送端口,这指向一个需要放置解压文件的文件夹。

我尝试用谷歌搜索但没有成功,现有的样本似乎对我不起作用。

所以任何人都可以帮助我或告诉我在我的代码中做错了什么。我只想实现一个 C# 自定义 BizTalk 2013 R2(接收或发送)管道,该管道可以将包含一些 txt 文件的接收到的 GZ 文件解压缩到发送端口(指向文件夹)?

更新:

由于 Dissambler 版本不起作用,我创建了一个解码版本。

这是管道中的解码代码:

                #region IComponent members
    /// <summary>
    /// Implements IComponent.Execute method.
    /// </summary>
    /// <param name="pc">Pipeline context</param>
    /// <param name="inmsg">Input message</param>
    /// <returns>Original input message</returns>
    /// <remarks>
    /// IComponent.Execute method is used to initiate
    /// the processing of the message in this pipeline component.
    /// </remarks>
    public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pc, Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg)
    {
        if (null == pc) throw new ArgumentNullException("pContext", "Pipeline context can not be null");

        if (null == inmsg) throw new ArgumentNullException("pInMsg", "Input message can not be null");

        IBaseMessagePart bodyPart = inmsg.BodyPart;

        if (bodyPart != null)
        {
            GZipStream strm = new GZipStream(bodyPart.GetOriginalDataStream(), CompressionMode.Decompress);
            bodyPart.Data = strm;
            pc.ResourceTracker.AddResource(strm);
        }

        return inmsg;
    }
    #endregion

如何获取 GZip 文件中每个文件的正确文件名?所以当消息被发送到发送端口时,它应该用正确的文件名写入文件。

【问题讨论】:

  • 您好,它不会抛出任何错误,只是发送 GZ 文件而不将其解包到发送端口。我在接收位置端口使用已实现的管道。以下是它的工作原理:当 BizTalk 在其接收位置接收到 GZ 打包文件时,它只是将文件发送到订阅此接收位置的发送端口。管道似乎对 GZ 流没有任何作用。它应该做的是解压GZ文件并将所有解压后的文件发送到发送端口,hvis指向需要放置解压文件的文件夹。
  • 我只是想知道我是否需要在管道中实现一个 Disassemble 或 Decoder 部分来解压缩 gz 文件。?
  • 然后编辑您的问题并将这些详细信息添加到问题中。我倾向于把它放在管道的解码部分,因为如果需要,你还可以在它之后执行一个平面文件或 xml 反汇编器管道组件,你不能有两个组件都在反汇编器阶段执行“如果此阶段包含多个组件,仅运行第一个识别消息格式的组件。如果阶段内的组件都没有识别消息格式,则消息处理失败。 msdn.microsoft.com/en-us/library/ee268059(v=bts.10).aspx
  • 您是否尝试过将 Visual Studio 附加到主机进程并在您的自定义管道组件中放置一个断点?
  • 在 Stackoverflow 上主要更改问题以使答案无效被认为是不好的做法。在这种情况下,您应该做的是将新问题作为新问题发布(参考原始问题是否可以澄清问题)或向问题添加额外细节(正如我通过回滚和编辑所做的那样)。

标签: c# biztalk biztalk-2013r2 custom-pipeline-component biztalk-pipelines


【解决方案1】:

看起来您将自定义管道组件实现为 Disassemble 阶段,它实际上应该是 Decode 阶段管道组件,原因如下。

  1. 在反汇编阶段,您只能让一个组件执行。这意味着您不能同时执行平面文件、XML 或 JSON 反汇编程序。
  2. 如果是反汇编阶段的组件,还需要实现一个probe,看消息是否被识别,否则不执行。

见 MSDN Receive Pipelines

解码阶段

  • 此阶段用于解码或解密消息的组件。
    • 如果传入的消息需要从一种格式解码为另一种格式,则应将 MIME/SMIME 解码器管道组件或自定义解码组件放置在此阶段。
  • 此阶段接收一条消息并生成一条消息。
  • 此阶段可以包含 0 到 255 个组件。
  • 此阶段的所有组件均已运行。

拆机阶段

此阶段用于解析或反汇编消息的组件。

  • 此阶段中的组件探测消息以查看消息的格式是否被识别。根据对格式的识别,其中一个组件会反汇编消息。
  • 如果此阶段包含多个组件,则仅运行识别消息格式的第一个组件。如果阶段内的任何组件都不能识别消息格式,则消息处理失败。
  • 此阶段应包括任何实现特殊行为以分解消息内容的自定义组件。
  • 此阶段可以包含 0 到 255 个组件。如果阶段中没有组件,则传递消息。

更新:随着您问题的更新,它变得有点棘手。如果您必须将一条消息拆分为多条消息,那么您可以执行的唯一阶段是 Disassemble 阶段。所以你必须回到那个版本并调试它并找出它为什么不执行解压缩。

Zip Disassembler UnzipDisassembler - A custom pipeline component for BizTalk Server 2004 的旧代码示例用于 Zip 文件而不是 Gzip。但它遵循相同的模式。您还需要一个类似于 GetNextEntry 的方法来发布消息,然后解析下一个文件。在 outmsg 创建阶段,您可以设置文件名等上下文属性。

【讨论】:

  • 您好,谢谢。我从 BizTalk 2006 SDK 中找到了一个示例,并按照您提到的那样创建了一个解码管道,现在它工作正常。但是我在获取正确的文件名时遇到了一些问题,似乎它对所有文件都使用了 gzip 文件名。我只是更改了上面的代码示例。
猜你喜欢
  • 2017-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多