Azure C#WebJob归档块Blob集写入所有0字节的归档映像
脚本的功能目的是接收容器中的blob名称数组。并创建一个.ZIP文件,以后可以下载 经过一些研究,我能够触发WebJob并将图像添加到存档中,然后将其上传回Blob存储。问题是所有文件都没有字节。我对C#中的流是完全陌生的,但一直以来都是在这样的前提下操作的:我只需将最终的归档流写回blob存储,就可以根据需要简单地通过管道传输数据 我的假设是错误的吗 我怀疑我的问题与在图像中循环时的一些异步操作有关,在写入和上载存档之前,这些操作永远不会完成 代码如下,任何帮助都将不胜感激Azure C#WebJob归档块Blob集写入所有0字节的归档映像,c#,azure,azure-webjobs,C#,Azure,Azure Webjobs,脚本的功能目的是接收容器中的blob名称数组。并创建一个.ZIP文件,以后可以下载 经过一些研究,我能够触发WebJob并将图像添加到存档中,然后将其上传回Blob存储。问题是所有文件都没有字节。我对C#中的流是完全陌生的,但一直以来都是在这样的前提下操作的:我只需将最终的归档流写回blob存储,就可以根据需要简单地通过管道传输数据 我的假设是错误的吗 我怀疑我的问题与在图像中循环时的一些异步操作有关,在写入和上载存档之前,这些操作永远不会完成 代码如下,任何帮助都将不胜感激 public st
public static void ArchiveImagesTask(
[QueueTrigger("download")] AssetImagesArchive assetImages,
string id,
string email,
string container,
string[] images,
[Blob("{container}")] CloudBlobContainer sourceContainer,
[Blob("downloads")] CloudBlobContainer targetContainer)
{
using (var memoryStream = new MemoryStream())
{
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
{
foreach (var image in images)
{
var blobInArchive = archive.CreateEntry(image, CompressionLevel.Optimal);
var blob = sourceContainer.GetBlockBlobReference(image);
using (var entryStream = blobInArchive.Open())
using (var fileToCompressStream = new MemoryStream(blob.StreamWriteSizeInBytes))
{
fileToCompressStream.CopyTo(entryStream);
}
}
}
var zip = targetContainer.GetBlockBlobReference($"{id}.zip");
memoryStream.Seek(0, SeekOrigin.Begin);
zip.UploadFromStream(memoryStream);
}
}
问题似乎在这里:
using (var entryStream = blobInArchive.Open())
using (var fileToCompressStream = new MemoryStream(blob.StreamWriteSizeInBytes))
{
fileToCompressStream.CopyTo(entryStream);
}
您的entryStream
是您写入的流,以便添加到zip文件中(如果我正确理解了您的代码的话)-所以这很好。
但是,您正在创建一个新的空fileToCompressStream
,其中没有任何内容;您只是传入一个整数,它是流的大小(我不知道它是如何编译的,但那是另一回事)。因此,您正在向Zip文件添加一个空流
您应该能够用此(未测试)替换上述三条线
看
如果出现奇怪的异常情况而失败——这可能是因为.Net中的流在很大程度上违反了Liskov替换原则——您可能需要这样做
using (var entryStream = blobInArchive.Open())
using (var fileToCompressStream = new MemoryStream(blob.StreamWriteSizeInBytes))
{
blob.DownloadToStream(fileToCompressStream);
fileToCompressStream.Position = 0; // Not sure this is necessary
fileToCompressStream.CopyTo(entryStream);
}
…但只有在必要时才这样做;如果这样做的话,您将在内存中保留整个文件的另一个副本
如果在此之后仍然存在问题,则可能需要手动刷新部分流;您正在使用的using
语句将调用流上的Dispose方法,该方法将刷新流,但总有可能有人没有正确实现
旁注
您加入这一行是非常正确的:
memoryStream.Seek(0, SeekOrigin.Begin);
它将流中的指针设置回起始位置,以便在上载时实际向上发送数据。您可能想知道,MemoryStream有一种稍微简单一点的方法,即:
memoryStream.Position = 0;
这对结果没有影响,我个人更喜欢这种语法。先生,你简直太棒了!到目前为止,第一次迭代处理了多达20幅图像。同样感谢您提供更多详细信息!
memoryStream.Position = 0;