У меня есть два двоичных набора данных в adf, один использует сжатие .zip, второй — без сжатия.
Поэтому я использую эти два набора данных в качестве источника и приемника для действия CopyData для распаковки файлов в хранилище BLOB-объектов, и это прекрасно работает, когда у меня есть только zip-файл с несколькими текстовыми файлами внутри.
Но неожиданное поведение возникает, когда мне нужно разархивировать файл, внутри которого есть другие zip-файлы. В качестве ожидаемого результата я хочу видеть папку с именем «основной архив» и несколько zip-архивов внутри нее.
main_archive.zip/
|- nested1.zip
|- nested2.zip
Но вместо zip-архивов я вижу папки с названиями вложенных zip-архивов и разархивированные файлы внутри них.
main_archive.zip/
|- nested1.zip/
|- file1.txt
|- nested2.zip/
|- file2.txt
Я не понимаю, почему я сталкиваюсь с такой ситуацией, в то время как другие задают вопросы «как сразу разархивировать вложенные архивы» и получают ответ: «adf не поддерживает вложенное разархивирование одной операцией».
Мне нужно, чтобы эти вложенные архивы были сжаты. Есть предположения?
Я попробовал ваш сценарий и получил те же результаты.
Он рекурсивно распаковывает каждый внутренний zip-файл. Я попробовал тот же сценарий в интегрированных конвейерах Synapse, и в этом случае результат тот же.
Ранее он использовался для распаковки только данного zip-файла. Но в настоящее время неясно, является ли такое поведение новой функцией или ошибкой. Я разместил запрос на Github, за которым вы можете следить.
Поскольку ваш корневой zip-файл содержит zip-файлы только на уровне подпапки, в этом случае вы можете попробовать обходной путь ниже. При таком подходе необходимые zip-файлы создаются из разархивированных папок и удаляются.
После действия копирования создайте действие «Получить метаданные» с двоичным набором данных и установите поле ChildItems
. Путь к двоичному набору данных должен быть вашей целевой разархивированной папкой, которая в моем случае равна zipsoutout/mainzip.zip
и не указывает тип сжатия.
Это даст список всех имен папок и имен файлов. Отфильтруйте имена распакованных папок из этого списка, используя действие фильтра. Имена папок, содержащие .zip
в конце, относятся к разархивированным папкам.
Укажите приведенные ниже выражения в качестве элементов и условий для действия фильтра.
Items : @activity('Get Metadata1').output.childItems
condition : @endswith(item().name, '.zip')
Теперь передайте этот выходной массив действия фильтра @activity('Filter1').output.value
выражению действия For-each.
Внутри For-Each выполните действие копирования, чтобы заархивировать папки. Передайте тот же набор данных, который ранее использовался в действии «Получение метаданных», в источник действия копирования с приведенными ниже конфигурациями.
@concat('mainzip.zip/',item().name)
Создайте новый двоичный набор данных с тем же путем к папке, но для пути к файлу, создайте параметр набора данных и используйте его в имени файла. Также укажите требуемый тип сжатия.
Назначьте этот набор данных в качестве приемника действия копирования и используйте @item().name
для параметра набора данных в действии копирования.
Это действие копирования создаст необходимый zip-файл. Теперь, чтобы удалить существующие распакованные папки, используйте действие «Удалить». Для этого требуется другой набор двоичных данных.
Создайте параметр набора данных и используйте его в имени папки набора данных, как показано ниже.
В действии удаления используйте приведенное ниже выражение в качестве значения для вышеуказанного параметра и следуйте приведенным ниже конфигурациям.
@concat('mainzip.zip/',item().name)
Это приведет к удалению всего содержимого разархивированных папок. Поскольку вы используете хранилище BLOB-объектов, пустые папки будут удалены автоматически.
Теперь отладьте конвейер, и он создаст необходимые внутренние zip-файлы.