BLOB-триггер - проблема с обработкой zip-файла, который структурирован как folder.zip> folder> (170 файлов-gif, png, txt и т. Д.) - PullRequest
0 голосов
/ 01 апреля 2019

У меня есть приложение-функция Azure, которое является триггером BLOB-объектов. Он обнаруживает новые ZIP-файлы в контейнере BLOB-объектов и извлекает их в новый контейнер. Он отлично работает для zip-файлов, которые структурированы как file.zip> (170 элементов, таких как gifs, pngs, txt, html), но не могут обрабатывать zip-файлы, структурированные как file.zip> file> (170 элементов, таких как gifs, pngs, txt) ). Должен ли я использовать другую библиотеку или есть проблема с кодом?

using System;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;

namespace IV4.Function
{
    public static class iv4Unzipthis
    {
        [FunctionName("Unziptestiv4")]
        public static async Task Run([BlobTrigger("input-files/{name}", Connection = "unzip_STORAGE")]Stream myBlob, string name, ILogger log)
        {
            log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name} \n Size: {myBlob.Length} Bytes");

            string destinationStorage = Environment.GetEnvironmentVariable("destinationStorage");
            string destinationContainer = Environment.GetEnvironmentVariable("destinationContainer");

            try{
                if(name.Split('.').Last().ToLower() == "zip"){

                    ZipArchive archive = new ZipArchive(myBlob);

                    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(destinationStorage);
                    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
                    CloudBlobContainer container = blobClient.GetContainerReference(destinationContainer);

                    foreach (ZipArchiveEntry entry in archive.Entries)
                    {
                        log.LogInformation($"Now processing {entry.FullName}");

                        CloudBlockBlob blockBlob = container.GetBlockBlobReference(entry.Name);
                        using (var fileStream = entry.Open())
                        {
                           await blockBlob.UploadFromStreamAsync(fileStream);
                        }
                    }
                }
            }
            catch(Exception ex){
                log.LogInformation($"Error! Something went wrong: {ex.Message}");

            }            
        }
    }
}

Я беру только 1 элемент файла из этих 170 и выдает ошибку для других элементов в папке. вот лог потока для исполнения-

2019-04-01T14: 14: 54.814 [Информация] C # Функция запуска BLOB-объекта Обработанный BLOB-объект

Имя: Scan_Report.zip

Размер: 407942 Байт

2019-04-01T14: 14: 54.858 [Информация] Сейчас обрабатывается Scan_Report / index.html

2019-04-01T14: 14: 54.928 [Информация] Сейчас обрабатывается Scan_Report /

2019-04-01T14: 14: 54,928 [Информация] Ошибка! Что-то пошло не так: аргумент не должен быть пустой строкой.

Имя параметра: blobName

2019-04-01T14: 14: 54.929 [Информация] Выполнено 'Unziptestiv4' (Успешно, Id = 8fa15f91-928c-4010-93b1-4da9af43bbc3)

1 Ответ

0 голосов
/ 02 апреля 2019

При использовании file.zip>file>(170 items like gifs, pngs, txt) будет путь без имени файла, например "file.zip/file/", и это приведет к ошибке (другие правильные, например file.zip/file/11.txt).

Пожалуйста, попробуйте код ниже и отлично работает на моей стороне, просто добавьте if (entry.FullName.EndsWith("/")) { continue; } в коде foreach(), как показано ниже:

                    //your other code

                    foreach (ZipArchiveEntry entry in archive.Entries)
                    {
                        // add this line of code.
                        if (entry.FullName.EndsWith("/")) { continue; }

                        log.LogInformation($"Now processing {entry.FullName}");

                        CloudBlockBlob blockBlob = container.GetBlockBlobReference(entry.Name);
                        using (var fileStream = entry.Open())
                        {
                            await blockBlob.UploadFromStreamAsync(fileStream);
                        }
                    }
...