Разделить плоские файлы на более мелкие файлы (по количеству строк) с помощью пользовательского конвейера
Я пытаюсь создать пользовательский конвейерный компонент для BizTalk 2010, который разбивает входящий плоский файл на несколько небольших файлов. Я хочу разбить файл (скажем, ~30 000 строк) на файлы по 5000 строк каждый или чуть меньше (скажем, если файл содержит 33 000 строк).
Я попытался использовать отличный пример Selvan для индивидуального конвейера разборки, но безрезультатно.
Я использовал Мастер компонентов конвейера для создания скелета конвейера, но был бы очень рад любым советам или указателям о том, как приступить к написанию кода этапа разбора и разбиению большого файла. Я в значительной степени новичок в этом типе кодирования.
Любая помощь?
1 ответ
Разделение сообщений может быть выполнено только с помощью компонента дизассемблера. Вы можете создать класс, который наследует от существующего дизассемблера (например, как сделал Селвин), или вы можете указать, что вы хотите создать тип компонента "DisassemblyParser" для типа принимаемого конвейера в мастере компонентов конвейера. Наследование полезно, если вы можете повторно использовать свойства времени разработки, но не обязательно.
При запуске BizTalk передает сообщение с помощью метода "дизассемблирования". После того, как этот метод возвращает, BizTalk начинает опрашивать метод "GetNext", пока не вернет ноль, чтобы получить все выходные сообщения. Итак, вам нужно спроектировать, как вы собираетесь подготовить сообщение в методе "Disassemble", чтобы вы могли возвращать требуемые разделенные сообщения, когда BizTalk вызывает "GetNext".
Подход Сельвана таков:
- В "Disassemble" преобразуйте весь плоский файл в XML с помощью дизассемблера BizTalk для плоских файлов (base.Disassemble) и позвольте базовому классу хранить выходные данные XML
- В первый раз, когда BizTalk вызывает "GetNext", неразделенное XML-сообщение извлекается из базового класса (base.GetNext) и загружается в XPathDocument и разделяется на основе количества узлов. Новое сообщение создается для каждой части и сохраняется в коллекции.
- Каждый вызов GetNext возвращает одно из сообщений из коллекции сообщений, пока все они не будут возвращены, поэтому метод возвращает null.
Как он отмечает, использование XPathNavigator не подходит для очень больших сообщений. Всегда лучше использовать XmlReader, когда это возможно, чтобы сообщение могло быть обработано как поток без полной загрузки в память. Это можно сделать, изменив процесс GetNext следующим образом:
- Первый раз это называется создание XmlReader для разобранного потока сообщений XML.
- Для каждого вызова GetNext используйте XmlReader для чтения вперед необходимого количества узлов при записи в новый поток вывода, который возвращается с новым сообщением BizTalk.
- Когда вы достигли конца сообщения XML, вы можете закрыть читатель и вернуть ноль.
Из вашего описания звучит так, как будто вы захотите выводить плоские файлы без их разборки в XML, и в этом случае я бы предложил просто сохранить поток ввода при вызове Disassemble и затем использовать тот же дизайн GetNext, но с StreamReader вместо XmlReader,