4

я 2 файлы, сохраненные на Лазурном хранилище больших двоичных объектов:не сможет правильно скачивать файлы с лазурной хранения и данные теряются слишком при загрузке файлов

  1. abc.txt
  2. Pqr.docx

Теперь я хочу создать zip-файлы из этих 2-х файлов и разрешить загрузку пользователя.

Я сохранил это в моем поле таблицы базы данных, как это:

Document 
Abc,Pqr 

Теперь, когда я нажимаю на загрузку затем я получаю файл, как показано ниже без данных в нем и расширение файла теряются слишком, как показано ниже: enter image description here

Я хочу, чтобы пользователь, чтобы получить точный файл (.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; 
     } 

Я хочу тот же файл будет загружен, если пользователь загрузить файл почтового индекса.

Может ли кто-нибудь помочь мне с этим?

ответ

1

Есть две вещи, которые я заметил:

  1. После того, как вы читаете содержимое двоичных объектов в потоке, вы не возвратные положение этого потока на 0. Таким образом, все файлы в zip имеют нулевые байты.
  2. При вызове 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"); 
    } 
+0

Большое спасибо gaurav.Now, можете ли вы рассказать мне, как вернуть этот zip-файл из моего метода контроллера, потому что я плохо застрял в этом только. –

+1

Я думаю, что код, который у вас есть, должен работать - 'return File (outputStream," application/zip "," all.zip ");'. Вы получаете там ошибку? –

+0

Нужно ли это делать D: \\ output.zip? –

1

Я видел людей, использующих библиотеку ICSharpZip, посмотрите на этот кусок кода

Взято отсюда generate a Zip file from azure blob storage files

+0

Извините, что я не могу использовать другую Zip-библиотеку и, самое главное, как я могу вернуть ее с моего контроллера mvc ?? –

2

Я не веб-DEV, но, надеюсь, это поможет. Этот фрагмент кода находится в методе, в котором я загружаю список блобов в архив 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 
+0

Не могли бы вы рассказать мне, как мне интегрировать это с моим контроллером mvc, потому что основная проблема связана с моим контроллером, как, например, как мой метод контроллера? –

 Смежные вопросы

  • Нет связанных вопросов^_^