Как мне распаковать файл gzip в пользовательском конвейере
Я попытался создать собственный конвейер BizTalk 2013 R2 (получение или отправка), который может распаковать файл xxx.GZ, содержащий некоторые текстовые файлы, в порт отправки.
Вот что я пробовал до сих пор:
PS. Я использовал классы.Net IO GZip.
Создано приложение BTS, настроено местоположение приема и порт отправки.
Местоположение получения использует пользовательский конвейер, который я создал, вот мой код пользовательского конвейера, который я пробовал:
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 ответ
Похоже, что вы реализовали пользовательский компонент конвейера в качестве этапа дизассемблирования, на самом деле он должен быть компонентом этапа конвейера декодирования по следующим двум причинам.
- На этапе дизассемблирования у вас может быть только один исполняемый компонент. Это означает, что вы также не сможете запустить простой файл, XML или JSON disasembler.
- Если это компонент этапа дизассемблирования, вам также необходимо реализовать проверку, чтобы увидеть, распознано ли сообщение, иначе оно не будет выполнено.
См. MSDN Получающие конвейеры
Этап декодирования
- Этот этап используется для компонентов, которые декодируют или дешифруют сообщение.
- Компонент конвейера MIME/SMIME Decoder или компонент пользовательского декодирования должен быть размещен на этом этапе, если входящие сообщения необходимо декодировать из одного формата в другой.
- Этот этап занимает одно сообщение и создает одно сообщение.
- Эта стадия может содержать от нуля до 255 компонентов.
- Все компоненты на этом этапе запускаются.
Разберите сцену
Этот этап используется для компонентов, которые анализируют или разбирают сообщение.
- Компоненты на этом этапе проверяют сообщение, чтобы узнать, распознан ли формат сообщения. Основываясь на распознавании формата, один из компонентов разбирает сообщение.
- Если этот этап содержит более одного компонента, запускается только первый компонент, который распознает формат сообщения. Если ни один из компонентов на этапе не распознает формат сообщения, обработка сообщения не выполняется.
- Этот этап должен включать любые пользовательские компоненты, которые реализуют специальное поведение для дизассемблирования содержимого сообщения.
- Эта стадия может содержать от нуля до 255 компонентов. Если на стадии нет компонентов, сообщение пропускается.
Обновление: с обновлением вашего вопроса это становится немного сложнее. Если вам нужно разделить сообщение на несколько сообщений, единственный этап, на котором вы можете это сделать, - это этап "Разборка". Поэтому вам придется вернуться к этой версии, отладить ее и выяснить, почему она не выполняет распаковку.
Существует старый пример кода для дизассемблера Zip UnzipDisassembler - пользовательский конвейерный компонент для BizTalk Server 2004, предназначенный для Zip-файла, а не для Gzip. Но это следует той же схеме. Также вам понадобится метод, аналогичный GetNextEntry, для публикации сообщения и последующего анализа следующего файла. Именно на этапе создания outmsg вы можете установить свойства контекста, такие как имя файла.