c# - Azure 功能:解压缩文件在调试中有效,但在生产中无效
问题描述
这是我的第一个 Azure 函数。在将文件上传到 Azure 存储 Blob 后,我需要解压缩文件。
我发现了这个视频https://www.youtube.com/watch?v=GRztpy337kU和这篇文章:https://msdevzone.wordpress.com/2017/07/07/extract-a-zip-file-stored-in -天蓝色斑点。
使用带有 C# 的 Visual Studio 2017,当我在 Visual Studio 中运行该函数时一切正常,但是当我将它部署到 Azure 时,没有提取任何内容。如果我看日志,一切似乎都很好。
这是我的代码:
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 中的日志:
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
一切似乎都很好,但在函数结束时容器输出文件是空的!
我究竟做错了什么?
解决方案
除了我上面的评论(无论如何请这样做!),你的问题在这里:
blockBlob.UploadFromStreamAsync(fileStream);
它需要改为:
await blockBlob.UploadFromStreamAsync(fileStream);
和你的功能本身:
public static async Task Run([BlobTrigger("input-files/{name}", Connection = "connectionStorage")] Stream myBlob, string name, TraceWriter log)
//编辑:所以这是一个使用输出绑定的完整示例。请注意,如果您愿意,当然也可以使用两个不同的连接字符串(两个不同的存储帐户)进行触发器和输出绑定。
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");
}
}
}
}
推荐阅读
- python - 物体中心到图像中心的距离
- c# - 将列表框的所有项目发送到列表视图的第一列。但是listview是另一种形式
- tcp - 无法使用 Fluentd @tcp 捕获 syslog 客户端 IP 地址
- php - 如何在 PHP 中将多个变量传入和传出回调函数?
- excel - Excel计算行数,同时将合并的行视为一个
- python-3.x - 如何使用 python 在 telnet 会话中发出命令
- unix - Unix命令按顺序检查丢失的文件
- android - 无法导入 android.support.v7.widget.Toolbar
- python - 服务退出并出现异常代码:PyInstaller 文件中的 255
- eclipse - eclipse启动后如何禁用“JRebel入门”