2015-11-17 2 views
0
using Ionic.Zip 
... 
using (ZipFile zip = new ZipFile()) 
    { 
     zip.AlternateEncodingUsage = ZipOption.AsNecessary; 
     zip.AddDirectoryByName("Files"); 
     foreach (GridViewRow row in GridView1.Rows) 
     { 
      if ((row.FindControl("chkSelect") as CheckBox).Checked) 
      { 
       string filePath = (row.FindControl("lblFilePath") as Label).Text; 
       zip.AddFile(filePath, "Files"); 
      } 
     } 
     Response.Clear(); 
     Response.BufferOutput = false; 
     string zipName = String.Format("Zip_{0}.zip", DateTime.Now.ToString("yyyy-MMM-dd-HHmmss")); 
     Response.ContentType = "application/zip"; 
     Response.AddHeader("content-disposition", "attachment; filename=" + zipName); 
     zip.Save(Response.OutputStream); 
     Response.End(); 
    } 

Hello! Эта часть кода выполняет загрузку zipped-каталога. Предположим, у меня есть gridview СОДЕРЖАНИЯ текстовых файлов, которые я хочу скачать. Есть ли способ заставить программу загрузить такой архив без знания или записи путей к файлам?C# загрузка ZIP архива файлов, созданных веб-приложением

Код должен работать таким образом:

1. get item from gridview 
2. create a text file from the content 
3. add it to the zip directory 
(repeat foreach item in gridview) 
n. download a zipped file 

ответ

1

Согласно документации, вы можете add an entry from a Stream. Поэтому рассмотрим, где вы в настоящее время сделать это:

zip.AddFile(filePath, "Files"); 

Вместо добавления «файл» данный путь, вы бы добавить «файл» данный поток данных.

Таким образом, вы можете создать поток из строки:

new MemoryStream(Encoding.UTF8.GetBytes(someString)) // or whatever encoding you use 

и добавить его в Zip:

using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(someString))) 
{ 
    zip.AddEntry(someFileName, stream); 
    // other code 
    zip.Save(Response.OutputStream); 
} 

Одна вещь, чтобы отметить здесь, что ваше управление ресурсами и утилизации (с using блоков) может получить немного сложнее. Это связано с тем, что согласно документации:

Приложение должно обеспечивать открытый, читаемый поток; в этом случае он будет считан во время вызова Save() или одной из его перегрузок.

Что это означает, что если вы располагаете какой-либо из потоков перед тем вызова .Save(), она не будет выполнена, когда вы это называете. Возможно, вам захочется просмотреть документацию еще раз, чтобы узнать, есть ли способ заставить Zip читать потоки ранее в этом процессе. В противном случае вам в основном придется управлять кучей открытых потоков, пока не придет время «сохранить» Zip.


Edit: Похоже документации was right there ...

В тех случаях, когда большое количество потоков будет добавлено в ZipFile, приложение может пожелать, чтобы избежать сохранения всех потоки открываются одновременно. Чтобы справиться с этой ситуацией, приложение должно использовать перегрузку AddEntry (String, OpenDelegate, CloseDelegate).

Это будет немного сложнее и потребует, чтобы вы открыли/Таким образом, вам решать, как вы строите свою логику, предпочтительнее ли вам встраивать блоки using. Вероятно, это зависит от количества потоков, которые вы планируете использовать.

+0

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

+0

@Simon: В этом случае последний подход (в части «редактирования» ответа) будет способом. – David

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