Azure功能:解压缩文件可在调试中使用,但不能在生产中使用 [英] Azure Function: Unzip file works in debug but not in production

查看:54
本文介绍了Azure功能:解压缩文件可在调试中使用,但不能在生产中使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的第一个Azure函数.将文件上传到Azure存储Blob之后,我需要解压缩文件.
我发现此视频 https://www.youtube.com/watch?v=GRztpy337kU和此帖子: https://msdevzone.wordpress.com/2017/07/07/extract-a-zip-file-stored-in-azure-blob .
将Visual Studio 2017与C#结合使用时,当我在Visual Studio中运行该功能时一切正常,但是当我将其部署到Azure时,不会提取任何内容.如果我看日志,一切似乎都很好.
这是我的代码:

This is my very first Azure function. I need to unzip a file after it is uploaded on an Azure Storage Blob.
I found this video https://www.youtube.com/watch?v=GRztpy337kU and this post: https://msdevzone.wordpress.com/2017/07/07/extract-a-zip-file-stored-in-azure-blob.
Using Visual Studio 2017 with C#, all works fine when i run the function in Visual Studio but when i deploy it to Azure, nothing is extracted. If i watch the log all seems ok.
Here is my code:

using System;
using System.IO;
using System.IO.Compression;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.WindowsAzure.Storage;

namespace ExtractZipFunction
{
    public static class ScompattaZip
    {
        [FunctionName("ScompattaZip")]
        public static void Run([BlobTrigger("input-files/{name}", Connection = "connectionStorage")]
                                Stream myBlob, string name, TraceWriter log)

        {
            log.Info($"C# Blob trigger function Processed blob\n Name:{name} \n Size: {myBlob.Length} Bytes");
            try
            {
                string destinationStorage = Environment.GetEnvironmentVariable("destinationStorage");
                string destinationContainer = Environment.GetEnvironmentVariable("destinationContainer");
                log.Info($"destinationStorage: {destinationStorage}");
                log.Info($"destinationContainer: {destinationContainer}");

                if (System.IO.Path.GetExtension(name).ToLower() == ".zip")
                {
                    log.Info("It's a zip");
                    var archive = new ZipArchive(myBlob);
                    var storageAccount = CloudStorageAccount.Parse(destinationStorage);
                    var blobClient = storageAccount.CreateCloudBlobClient();
                    var container = blobClient.GetContainerReference(destinationContainer);

                    foreach (var entry in archive.Entries)
                    {
                        var blockBlob = container.GetBlockBlobReference(entry.FullName);
                        using (var fileStream = entry.Open())
                        {
                            if (entry.Length > 0)
                            {
                                log.Info($"Estrazione 1 - {entry.FullName}");
                                blockBlob.UploadFromStreamAsync(fileStream);
                                log.Info($"Estrazione 2 - {entry.FullName}");
                            }
                        }
                    }
                }
                else
                    log.Info("Not a zip");
            }
            catch (Exception ex)
            {
                log.Info($"Errore: {ex.Message}");
            }
        }
    }
}

这是Azure中的日志:

And this is the log in Azure:

C# Blob trigger function Processed blob
 Name:EmptyJSONFile_1033.zip 
 Size: 24294 Bytes
destinationStorage: DefaultEndpointsProtocol=https;AccountName=[...]
destinationContainer: outputfiles
E' uno zip
Estrazione EmptyJSONFile_1033.ico
Estrazione 1 - EmptyJSONFile_1033.ico
Estrazione 2 - EmptyJSONFile_1033.ico
Estrazione EmptyJSONFile_1033.vstemplate
Estrazione 1 - EmptyJSONFile_1033.vstemplate
Estrazione 2 - EmptyJSONFile_1033.vstemplate
Estrazione json.json
Estrazione 1 - json.json
Estrazione 2 - json.json

一切似乎都还可以,但是在函数结尾处,容器的输出文件为空!

All seems OK but at the end of the function the container outputfiles is empty!

我在做什么错了?

推荐答案

除了我上面的评论(无论如何,请这样做!),您的问题在这里:

Except for my comment above (please do this anyway!), you issue is here:

blockBlob.UploadFromStreamAsync(fileStream);

它应该改为:

await blockBlob.UploadFromStreamAsync(fileStream);

和您的函数本身:

public static async Task Run([BlobTrigger("input-files/{name}", Connection = "connectionStorage")] Stream myBlob, string name, TraceWriter log)

//Edit:所以这是使用输出绑定的完整示例.请注意,如果愿意,您当然也可以使用两个不同的连接字符串(两个不同的存储帐户)进行触发和输出绑定.

// So here is a full example using output bindings. Note that you can of course also use two different connection strings (two different storage accounts) for trigger and output binding if you like to.

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

namespace SampleFunctions
{
    public static class UnzipBlob
    {
        /// <summary>
        /// This function is triggered by new blobs (should be a ZIP file) 
        /// and extracts the contents of the zip as new, individual blobs to a storage account
        /// </summary>
        /// <param name="inputBlob"></param>
        /// <param name="inputBlobName"></param>
        /// <param name="outputContainer"></param>
        /// <param name="log"></param>
        /// <returns></returns>
        [FunctionName("UnzipBlob")]
        public static async Task Run([BlobTrigger("input-zips/{inputBlobName}", Connection = "AzureWebJobsStorage")] Stream inputBlob, string inputBlobName,
            Binder binder,
            ILogger log)
        {
            log.LogInformation($"Blob trigger function received blob\n Name:{inputBlobName} \n Size: {inputBlob.Length} Bytes");

            if (Path.GetExtension(inputBlobName)?.ToLower() == ".zip")
            {
                // We use the first char of the input file name as a dynamic part in the container. (Note: You should check if this is a valid char for the container name)
                var container = $"my-dynamic-container-{inputBlobName.Substring(0,1).ToLower()}";
                var attributes = new Attribute[]
                {
                        new BlobAttribute($"{container}", FileAccess.ReadWrite),
                        new StorageAccountAttribute("AzureWebJobsStorage")
                };
                var outputContainer = await binder.BindAsync<CloudBlobContainer>(attributes);
                await outputContainer.CreateIfNotExistsAsync();

                var archive = new ZipArchive(inputBlob);
                foreach (var entry in archive.Entries)
                {
                    // we write the output files to a directory with the same name as the input blob. Change as required
                    var blockBlob = outputContainer.GetBlockBlobReference($"{inputBlobName}/{entry.FullName}");
                    using (var fileStream = entry.Open())
                    {
                        if (entry.Length > 0)
                        {
                            log.LogInformation($"Extracting - {entry.FullName} to - {blockBlob.Name}");
                            await blockBlob.UploadFromStreamAsync(fileStream);
                        }
                    }
                }
            }
            else
            {
                log.LogInformation("Not a zip file. Ignoring");
            }
        }
    }
}

这篇关于Azure功能:解压缩文件可在调试中使用,但不能在生产中使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆