Azure C#WebJob归档块Blob集写入所有0字节的归档映像

Azure C#WebJob归档块Blob集写入所有0字节的归档映像,c#,azure,azure-webjobs,C#,Azure,Azure Webjobs,脚本的功能目的是接收容器中的blob名称数组。并创建一个.ZIP文件,以后可以下载 经过一些研究,我能够触发WebJob并将图像添加到存档中,然后将其上传回Blob存储。问题是所有文件都没有字节。我对C#中的流是完全陌生的,但一直以来都是在这样的前提下操作的:我只需将最终的归档流写回blob存储,就可以根据需要简单地通过管道传输数据 我的假设是错误的吗 我怀疑我的问题与在图像中循环时的一些异步操作有关,在写入和上载存档之前,这些操作永远不会完成 代码如下,任何帮助都将不胜感激 public st

脚本的功能目的是接收容器中的blob名称数组。并创建一个.ZIP文件,以后可以下载

经过一些研究,我能够触发WebJob并将图像添加到存档中,然后将其上传回Blob存储。问题是所有文件都没有字节。我对C#中的流是完全陌生的,但一直以来都是在这样的前提下操作的:我只需将最终的归档流写回blob存储,就可以根据需要简单地通过管道传输数据

我的假设是错误的吗

我怀疑我的问题与在图像中循环时的一些异步操作有关,在写入和上载存档之前,这些操作永远不会完成

代码如下,任何帮助都将不胜感激

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;