2009-03-25 31 views
23

Cần phải tự động đóng gói một số tệp vào tệp .zip để tạo gói SCORM, bất kỳ ai biết cách này có thể được thực hiện bằng mã? Có thể xây dựng cấu trúc thư mục động bên trong tệp .zip không?Làm thế nào để tạo và điền một tệp ZIP bằng ASP.NET?

+0

Bản sao có thể có của [Sử dụng System.IO.Đóng gói để tạo tệp ZIP] (http://stackoverflow.com/questions/6386113/using-system-io-packaging-to-generate-a-zip-file) – Will

Trả lời

14

Bạn không phải sử dụng thư viện bên ngoài nữa. System.IO.Packaging có các lớp có thể được sử dụng để thả nội dung vào một tệp zip. Nó không đơn giản, tuy nhiên. Here's a blog post with an example (của nó ở cuối, đào cho nó).


Liên kết không ổn định, vì vậy đây là ví dụ Jon được cung cấp trong bài đăng.

using System; 
using System.IO; 
using System.IO.Packaging; 

namespace ZipSample 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      AddFileToZip("Output.zip", @"C:\Windows\Notepad.exe"); 
      AddFileToZip("Output.zip", @"C:\Windows\System32\Calc.exe"); 
     } 

     private const long BUFFER_SIZE = 4096; 

     private static void AddFileToZip(string zipFilename, string fileToAdd) 
     { 
      using (Package zip = System.IO.Packaging.Package.Open(zipFilename, FileMode.OpenOrCreate)) 
      { 
       string destFilename = ".\\" + Path.GetFileName(fileToAdd); 
       Uri uri = PackUriHelper.CreatePartUri(new Uri(destFilename, UriKind.Relative)); 
       if (zip.PartExists(uri)) 
       { 
        zip.DeletePart(uri); 
       } 
       PackagePart part = zip.CreatePart(uri, "",CompressionOption.Normal); 
       using (FileStream fileStream = new FileStream(fileToAdd, FileMode.Open, FileAccess.Read)) 
       { 
        using (Stream dest = part.GetStream()) 
        { 
         CopyStream(fileStream, dest); 
        } 
       } 
      } 
     } 

     private static void CopyStream(System.IO.FileStream inputStream, System.IO.Stream outputStream) 
     { 
      long bufferSize = inputStream.Length < BUFFER_SIZE ? inputStream.Length : BUFFER_SIZE; 
      byte[] buffer = new byte[bufferSize]; 
      int bytesRead = 0; 
      long bytesWritten = 0; 
      while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) != 0) 
      { 
       outputStream.Write(buffer, 0, bytesRead); 
       bytesWritten += bytesRead; 
      } 
     } 
    } 
} 
+0

+1 cho liên kết cực kỳ hữu ích mà tác giả đang cập nhật. –

+0

Hãy xem liên kết này http://weblogs.asp.net/dneimke/archive/2005/02/25/380273.aspx – daitangio

+0

Liên kết bị hỏng – bpoiss

1

Tôi đã sử dụng một thành phần miễn phí từ chilkat cho điều này: http://www.chilkatsoft.com/zip-dotnet.asp. Có khá nhiều mọi thứ tôi cần nhưng tôi không chắc chắn về việc xây dựng cấu trúc tệp động.

+0

Chúng tôi cũng sử dụng thành phần này trong công ty của chúng tôi. Dựa trên các lỗi trong thành phần, một số dịch vụ căng thẳng cực đoan của chúng ta đã gây ra một lỗi EngineException. Sau khi có một vé hỗ trợ của Microsoft, chúng tôi quyết định chuyển sang SharpZLib. Đây là 2 năm trước. Tôi không biết thành phần này tốt đến mức nào? –

+0

Chúng tôi chưa bao giờ gặp bất kỳ vấn đề gì với nó, tuy nhiên được sử dụng trong các dịch vụ xuất khẩu thường chạy nhiều nhất mỗi giờ, nhưng thường là hàng ngày.Mã hóa cũng hữu ích như – Macros

20

DotNetZip là điều tuyệt vời cho việc này. Working example

Bạn có thể viết mã zip trực tiếp vào Response.OutputStream. Mã trông giống như sau:

Response.Clear(); 
    Response.BufferOutput = false; // for large files... 
    System.Web.HttpContext c= System.Web.HttpContext.Current; 
    String ReadmeText= "Hello!\n\nThis is a README..." + DateTime.Now.ToString("G"); 
    string archiveName= String.Format("archive-{0}.zip", 
             DateTime.Now.ToString("yyyy-MMM-dd-HHmmss")); 
    Response.ContentType = "application/zip"; 
    Response.AddHeader("content-disposition", "filename=" + archiveName); 

    using (ZipFile zip = new ZipFile()) 
    { 
     // filesToInclude is an IEnumerable<String>, like String[] or List<String> 
     zip.AddFiles(filesToInclude, "files");    

     // Add a file from a string 
     zip.AddEntry("Readme.txt", "", ReadmeText); 
     zip.Save(Response.OutputStream); 
    } 
    // Response.End(); // no! See http://stackoverflow.com/questions/1087777 
    Response.Close(); 

DotNetZip là miễn phí.

0

Tạo tệp ZIP "khi đang di chuyển" sẽ được thực hiện bằng cách sử dụng thành phần Rebex ZIP của chúng tôi.

Các mẫu sau đây mô tả nó đầy đủ, bao gồm việc tạo một thư mục con:

// prepare MemoryStream to create ZIP archive within 
using (MemoryStream ms = new MemoryStream()) 
{ 
    // create new ZIP archive within prepared MemoryStream 
    using (ZipArchive zip = new ZipArchive(ms)) 
    {    
     // add some files to ZIP archive 
     zip.Add(@"c:\temp\testfile.txt"); 
     zip.Add(@"c:\temp\innerfile.txt", @"\subfolder"); 

     // clear response stream and set the response header and content type 
     Response.Clear(); 
     Response.ContentType = "application/zip"; 
     Response.AddHeader("content-disposition", "filename=sample.zip"); 

     // write content of the MemoryStream (created ZIP archive) to the response stream 
     ms.WriteTo(Response.OutputStream); 
    } 
} 

// close the current HTTP response and stop executing this page 
HttpContext.Current.ApplicationInstance.CompleteRequest(); 
0

Nếu bạn đang sử dụng .NET Framework 4.5 hoặc mới hơn bạn có thể tránh các thư viện của bên thứ ba và sử dụng lớp học tự nhiên System.IO.Compression.ZipArchive.

Dưới đây là một mẫu mã nhanh chóng sử dụng một MemoryStream và một vài mảng byte đại diện cho hai tập tin:

byte[] file1 = GetFile1ByteArray(); 
byte[] file2 = GetFile2ByteArray(); 

using (MemoryStream ms = new MemoryStream()) 
{ 
    using (var archive = new ZipArchive(ms, ZipArchiveMode.Create, true)) 
    { 
     var zipArchiveEntry = archive.CreateEntry("file1.txt", CompressionLevel.Fastest); 
     using (var zipStream = zipArchiveEntry.Open()) zipStream.Write(file1, 0, file1.Length); 
     zipArchiveEntry = archive.CreateEntry("file2.txt", CompressionLevel.Fastest); 
     using (var zipStream = zipArchiveEntry.Open()) zipStream.Write(file2, 0, file2.Length); 
    } 
    return File(ms.ToArray(), "application/zip", "Archive.zip"); 
} 

Bạn có thể sử dụng nó bên trong một điều khiển MVC trả lại một ActionResult: cách khác, nếu bạn cần phải phisically tạo lưu trữ zip, bạn có thể lưu giữ MemoryStream vào đĩa hoặc thay thế hoàn toàn bằng FileStream.

Để biết thêm thông tin về chủ đề này, bạn cũng có thể read this post.

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