Как мне распаковать файл gzip в пользовательском конвейере

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

Я безуспешно пытался гуглить, и существующие образцы, похоже, не работают для меня.

Так может кто-нибудь помочь мне или сказать, что я делаю неправильно в моем коде. Я просто хочу реализовать пользовательский конвейер BizTalk 2013 R2 (получение или отправка) на C#, который может распаковать полученный файл 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? Поэтому, когда сообщение отправляется на порт отправки, оно должно записать файл с правильным именем файла.

1 ответ

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

  1. На этапе дизассемблирования у вас может быть только один исполняемый компонент. Это означает, что вы также не сможете запустить простой файл, XML или JSON disasembler.
  2. Если это компонент этапа дизассемблирования, вам также необходимо реализовать проверку, чтобы увидеть, распознано ли сообщение, иначе оно не будет выполнено.

См. MSDN Получающие конвейеры

Этап декодирования

  • Этот этап используется для компонентов, которые декодируют или дешифруют сообщение.
    • Компонент конвейера MIME/SMIME Decoder или компонент пользовательского декодирования должен быть размещен на этом этапе, если входящие сообщения необходимо декодировать из одного формата в другой.
  • Этот этап занимает одно сообщение и создает одно сообщение.
  • Эта стадия может содержать от нуля до 255 компонентов.
  • Все компоненты на этом этапе запускаются.

Разберите сцену

Этот этап используется для компонентов, которые анализируют или разбирают сообщение.

  • Компоненты на этом этапе проверяют сообщение, чтобы узнать, распознан ли формат сообщения. Основываясь на распознавании формата, один из компонентов разбирает сообщение.
  • Если этот этап содержит более одного компонента, запускается только первый компонент, который распознает формат сообщения. Если ни один из компонентов на этапе не распознает формат сообщения, обработка сообщения не выполняется.
  • Этот этап должен включать любые пользовательские компоненты, которые реализуют специальное поведение для дизассемблирования содержимого сообщения.
  • Эта стадия может содержать от нуля до 255 компонентов. Если на стадии нет компонентов, сообщение пропускается.

Обновление: с обновлением вашего вопроса это становится немного сложнее. Если вам нужно разделить сообщение на несколько сообщений, единственный этап, на котором вы можете это сделать, - это этап "Разборка". Поэтому вам придется вернуться к этой версии, отладить ее и выяснить, почему она не выполняет распаковку.

Существует старый пример кода для дизассемблера Zip UnzipDisassembler - пользовательский конвейерный компонент для BizTalk Server 2004, предназначенный для Zip-файла, а не для Gzip. Но это следует той же схеме. Также вам понадобится метод, аналогичный GetNextEntry, для публикации сообщения и последующего анализа следующего файла. Именно на этапе создания outmsg вы можете установить свойства контекста, такие как имя файла.

Другие вопросы по тегам