2015-04-15 12 views
10

Có cách nào đó có thể tạo một ZipArchive từ (các) tệp trong bộ nhớ (và không thực sự trên đĩa).Cách tạo ZipArchive từ các tệp trong bộ nhớ trong C#?

Sau đây là trường hợp sử dụng: Nhiều tệp được nhận trong biến số IEnumerable<HttpPostedFileBase>. Tôi muốn nén tất cả các tệp này lại với nhau bằng cách sử dụng ZipArchive. Vấn đề là ZipArchive chỉ cho phép CreateEntryFromFile, dự kiến ​​một đường dẫn đến tệp, khi tôi chỉ có các tệp trong bộ nhớ.

Câu hỏi: Có cách nào để sử dụng một 'dòng' để tạo ra các 'nhập' trong ZipArchive, vì vậy mà tôi có thể trực tiếp đưa vào nội dung của tập tin trong zip?

Tôi không muốn lưu tệp đầu tiên, tạo mã zip (từ đường dẫn tệp đã lưu) rồi xóa từng tệp.

Ở đây, attachmentFilesIEnumerable<HttpPostedFileBase>

using (var ms = new MemoryStream()) 
{ 
    using (var zipArchive = new ZipArchive(ms, ZipArchiveMode.Create, true)) 
    { 
     foreach (var attachment in attachmentFiles) 
     { 
      zipArchive.CreateEntryFromFile(Path.GetFullPath(attachment.FileName), Path.GetFileName(attachment.FileName), 
           CompressionLevel.Fastest); 
     } 
    } 
    ... 
} 
+3

Các bạn đã thử này http://stackoverflow.com/questions/12347775/ziparchive- create-invalid-zip-file/12350106 # 12350106? –

+0

Tại sao không tạo tệp tạm thời và sau đó phát hành khi lưu trữ hoàn tất? – RussDunn

+0

Tôi muốn tránh tạo một tệp tạm thời và xóa nó sau đó, nếu có thể. Đó là những gì tôi đã viết trong câu hỏi, nhưng nếu không có cách nào khác, thì tôi sẽ phải làm điều đó. – Flair

Trả lời

14

Vâng, bạn có thể làm điều này, sử dụng phương pháp ZipArchive.CreateEntry, như @AngeloReis chỉ ra trong các ý kiến, và mô tả here cho một vấn đề hơi khác nhau.

Mã của bạn sau đó sẽ trông như thế này:

using (var ms = new MemoryStream()) 
{ 
    using (var zipArchive = new ZipArchive(ms, ZipArchiveMode.Create, true)) 
    { 
     foreach (var attachment in attachmentFiles) 
     { 
      var entry = zipArchive.CreateEntry(attachment.FileName, CompressionLevel.Fastest); 
      using (var entryStream = entry.Open()) 
      { 
       attachment.InputStream.CopyTo(entryStream); 
      } 
     } 
    } 
    ... 
} 
+2

Làm việc như một say mê, cảm ơn! Tôi đã sử dụng nó để tạo một tệp zip của một loạt các tệp PDF mà tôi đã lưu trữ dưới dạng byte [] trong cơ sở dữ liệu. Không cần phải có hệ thống tập tin nào cả. Người dùng nhấp vào một nút và tệp .zip được tải xuống thông qua trình duyệt web của họ. (BTW, ở bên trong nhất "sử dụng" khối tôi thay vì sử dụng entryStream.Write (arrBytes, 0, arrBytes.Length); – ClearCloud8

+1

AttachFiles là gì? – Demodave

0

Trước hết nhờ @ Alex cho câu trả lời hoàn hảo.
Ngoài ra cho kịch bản mà bạn cần phải đọc từ hệ thống file:

using (var ms = new MemoryStream()) 
{ 
    using (var zipArchive = new ZipArchive(ms, ZipArchiveMode.Create, true)) 
    { 
     foreach (var file in filesAddress) 
     { 
      zipArchive.CreateEntryFromFile(file, Path.GetFileName(file)); 
     } 
    } 

    ... 
} 

với sự giúp đỡ của System.IO.Compression.ZipFileExtensions

Các vấn đề liên quan