It is not possible to correctly download files from the azure storage and data is also lost when downloading files

I have 2 files stored in storage using Azure:

  • abc.txt
  • Pqr.docx

Now I want to create zip files from these 2 files and allow the user to load.

I saved this in the database table field as follows:

Document
Abc,Pqr

Now, when I click on download, then I get the file, as shown below, without data , and the file extension is also lost , as shown below: enter image description here

I want the user to get the exact file (.txt, .docx) in the zip when the user uploaded the zip file .

This is my code:

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;
        }

I want the same file to be loaded when the user downloaded the zip file.

Can anyone help me with this?

+4
3

, :

  • , blob , 0. , zip .
  • AddEntry blob "File"+cnt.

, . , zip .

    static void SaveBlobsToZip()
    {
        string[] str = new string[] { "CodePlex.png", "DocumentDB.png" };
        var account = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true);
        var blobClient = account.CreateCloudBlobClient();
        var container = blobClient.GetContainerReference("images");
        using (var fs = new FileStream("D:\\output.zip", FileMode.Create))
        {
            fs.Position = 0;
            using (var ms1 = new MemoryStream())
            {
                using (ZipFile zip = new ZipFile())
                {
                    int cnt = 0;
                    foreach (string t in str)
                    {
                        var ms = new MemoryStream();
                        container.GetBlockBlobReference(t).DownloadToStream(ms);
                        ms.Position = 0;//This was missing from your code
                        zip.AddEntry(t, ms);//You may want to give the name of the blob here.
                        cnt++;
                    }
                    zip.Save(ms1);
                }
                ms1.Position = 0;
                ms1.CopyTo(fs);
            }
        }
    }

UPDATE

MVC ( , :), ). .

    public ActionResult DownloadImagefilesAsZip()
    {
        string[] str = new string[] { "CodePlex.png", "DocumentDB.png" }; //repossitory.GetDocumentsUrlbyId(id);//output:Abc.txt,Pqr.Docx
        CloudBlobContainer blobcontainer = GetCloudBlobContainer();// azureStorageUtility.GetCloudBlobContainer();
        MemoryStream ms1 = new MemoryStream();
        using (ZipFile zip = new ZipFile())
        {
            int cnt = 0;
            foreach (string t in str)
            {
                var ms = new MemoryStream();
                CloudBlockBlob blockBlob = blobcontainer.GetBlockBlobReference(t);
                blockBlob.DownloadToStream(ms);
                ms.Position = 0;//This was missing from your code
                zip.AddEntry(t, ms);//You may want to give the name of the blob here.
                cnt++;
            }
            zip.Save(ms1);
        }
        ms1.Position = 0;
        return File(ms1, "application/zip", "all.zip");
    }
+1

-, , , . , 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 because
            //  the slashes are different
            filesNotFound.Add(blobFile);
        }
        else
        {
            //blob listing has files with forward slashes; that 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 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
+2

, ICSharpZip,

public void ZipFilesToResponse(HttpResponseBase response, IEnumerable<Asset> files, string zipFileName)
    {
        using (var zipOutputStream = new ZipOutputStream(response.OutputStream))
        {
            zipOutputStream.SetLevel(0); // 0 - store only to 9 - means best compression
            response.BufferOutput = false;
            response.AddHeader("Content-Disposition", "attachment; filename=" + zipFileName);
            response.ContentType = "application/octet-stream";

            foreach (var file in files)
            {
                var entry = new ZipEntry(file.FilenameSlug())
                {
                    DateTime = DateTime.Now,
                    Size = file.Filesize
                };
                zipOutputStream.PutNextEntry(entry);
                storageService.ReadToStream(file, zipOutputStream);
                response.Flush();
                if (!response.IsClientConnected)
                {
                   break;
                }
            }
            zipOutputStream.Finish();
            zipOutputStream.Close();
        }
        response.End();
    }

Zip azure blob

+1

Source: https://habr.com/ru/post/1613146/


All Articles