asp.net-mvc - 无法从 azure 存储正确下载文件,下载文件时数据也会丢失

标签 asp.net-mvc azure azure-storage dotnetzip azure-blob-storage

我在 Azure Blob 存储上保存了 2 个文件:

  1. Abc.txt
  2. Pqr.docx

现在我想创建这两个文件的 zip 文件并允许用户下载。

我已将其保存在我的数据库表字段中,如下所示:

Document
Abc,Pqr

现在,当我点击下载时,我收到如下所示的文件,其中没有数据,并且文件扩展名也丢失了,如下所示: enter image description here

我希望用户在下载 zip 文件时获得 zip 中的确切文件(.txt、.docx)

这是我的代码:

public ActionResult DownloadImagefilesAsZip()
{
    string documentUrl = repossitory.GetDocumentsUrlbyId(id);//output:Abc.txt,Pqr.Docx
          if (!string.IsNullOrEmpty(documentUrl))
            {
                string[] str = documentUrl.Split(',');
                if (str.Length > 1)
                {
                    using (ZipFile zip = new ZipFile())
                    {
                        int cnt = 0;
                        foreach (string t in str)
                        {
                            if (!string.IsNullOrEmpty(t))
                            {
                                Stream s = this.GetFileContent(t);
                                zip.AddEntry("File" + cnt, s);

                            }
                            cnt++;
                        }
                        zip.Save(outputStream);
                        outputStream.Position = 0;
                        return File(outputStream, "application/zip", "all.zip");
                    }
                }

}

  public Stream GetFileContent(string fileName)
        {
            CloudBlobContainer container = this.GetCloudBlobContainer();
            CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);
            var stream = new MemoryStream();
            blockBlob.DownloadToStream(stream);
            return stream;
        }

 public CloudBlobContainer GetCloudBlobContainer()
        {
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["StorageConnectionString"].ToString());
            CloudBlobClient blobclient = storageAccount.CreateCloudBlobClient();
            CloudBlobContainer blobcontainer = blobclient.GetContainerReference("Mystorage");
            if (blobcontainer.CreateIfNotExists())
            {
                blobcontainer.SetPermissions(new BlobContainerPermissions { PublicAccess = BlobContainerPublicAccessType.Blob });
            }
            blobcontainer.SetPermissions(new BlobContainerPermissions { PublicAccess = BlobContainerPublicAccessType.Blob });
            return blobcontainer;
        }

我希望当用户下载 zip 文件时下载相同的文件。

谁能帮我解决这个问题吗?

最佳答案

我不是网络开发人员,但希望这会有所帮助。这段代码位于我使用流将 blob 列表下载到 zip 文件存档中的方法中。文件列表在各个方向上都有斜杠,因此这里有代码可以解决此问题,并确保我获得具有正确文本的 blob 引用(没有 URL,如果 blob 位于“文件夹”)。

我怀疑您的问题不在于使用内存流或二进制编写器。特异性有时会有所帮助。祝你好运。

using (ZipArchive zipFile = ZipFile.Open(outputZipFileName, ZipArchiveMode.Create))
{
    foreach (string oneFile in listOfFiles)
    {
        //Need the filename, complete with relative path. Make it like a file name on disk, with backwards slashes.
        //Also must be relative, so can't start with a slash. Remove if found.
        string filenameInArchive = oneFile.Replace(@"/", @"\");
        if (filenameInArchive.Substring(0, 1) == @"\")
            filenameInArchive = filenameInArchive.Substring(1, filenameInArchive.Length - 1);

        //blob needs slashes in opposite direction
        string blobFile = oneFile.Replace(@"\", @"/");

        //take first slash off of the (folder + file name) to access it directly in blob storage
        if (blobFile.Substring(0, 1) == @"/")
            blobFile = oneFile.Substring(1, oneFile.Length - 1);

        var cloudBlockBlob = this.BlobStorageSource.GetBlobRef(blobFile);
        if (!cloudBlockBlob.Exists()) //checking just in case
        {
            //go to the next file
            //should probably trace log this 
            //add the file name with the fixed slashes rather than the raw, messed-up one
            //  so anyone looking at the list of files not found doesn't think it's because
            //  the slashes are different
            filesNotFound.Add(blobFile);
        }
        else
        {
            //blob listing has files with forward slashes; that's what the zip file requires
            //also, first character should not be a slash (removed it above)

            ZipArchiveEntry newEntry = zipFile.CreateEntry(filenameInArchive, CompressionLevel.Optimal);

            using (MemoryStream ms = new MemoryStream())
            {
                //download the blob to a memory stream
                cloudBlockBlob.DownloadToStream(ms);

                //write to the newEntry using a BinaryWriter and copying it 4k at a time
                using (BinaryWriter entry = new BinaryWriter(newEntry.Open()))
                {
                    //reset the memory stream's position to 0 and copy it to the zip stream in 4k chunks
                    //this keeps the process from taking up a ton of memory
                    ms.Position = 0;
                    byte[] buffer = new byte[4096];

                    bool copying = true;
                    while (copying)
                    {
                        int bytesRead = ms.Read(buffer, 0, buffer.Length);
                        if (bytesRead > 0)
                        {
                            entry.Write(buffer, 0, bytesRead);
                        }
                        else
                        {
                            entry.Flush();
                            copying = false;
                        }
                    }
                }//end using for BinaryWriter

            }//end using for MemoryStream

        }//if file exists in blob storage

    }//end foreach file

} //end of using ZipFileArchive

关于asp.net-mvc - 无法从 azure 存储正确下载文件,下载文件时数据也会丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33338814/

相关文章:

linux - 将 JDK 安装到 Azure Batch 中池的计算节点

asp.net - 如何强制编译 ASP.NET MVC View ?

JQueryidleTimeout插件: How to display the dialog after the session is timedout on ASP. NET MVC页面

jquery - jqgrid 触发器 ("reloadGrid")导致 IE 显示“停止运行脚本”对话框

c# - 在 documentDb 中动态创建查询

java - 使用 jsch 连接到 azure 中托管的 sftp 服务器时连接重置

jquery - 未捕获的语法错误 : Unexpected token ILLEGAL. Html.Partial()

azure - 无法在链接的 ARM 模板之间传递安全值

json - Azure Synapse Analytics Json 扁平化

python - 在 azure 中哪里可以找到 "storage_account_name","storage_account_key","storage_container_name"?