2009-03-25 22 views
23

Chcesz dynamicznie pakować niektóre pliki do pliku .zip, aby utworzyć pakiet SCORM, czy ktoś wie, jak to zrobić za pomocą kodu? Czy możliwe jest również dynamiczne budowanie struktury folderów w pliku .zip?Jak utworzyć i wypełnić plik ZIP za pomocą ASP.NET?

+0

Prawdopodobny duplikat [Używanie System.IO.Packaging do generowania pliku ZIP] (http://stackoverflow.com/questions/6386113/using-system-io-packaging-to-generate-a-zip-file) – Will

Odpowiedz

14

Nie musisz już korzystać z biblioteki zewnętrznej. System.IO.Packaging zawiera klasy, których można użyć do upuszczania zawartości do pliku zip. Nie jest to jednak proste. Here's a blog post with an example (na końcu, wykop go).


Link nie jest stabilny, więc oto przykład Jon zamieszczony w poście.

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 za niezwykle przydatne łącze, które autor aktualizuje. –

+0

Zapoznaj się także z tym linkiem http://weblogs.asp.net/dneimke/archive/2005/02/25/380273.aspx – daitangio

+0

Łącze jest zerwane – bpoiss

1

Użyłem do tego darmowego komponentu z chilkat: http://www.chilkatsoft.com/zip-dotnet.asp. Czy prawie wszystko, co potrzebne, ale nie jestem pewien co do budowania dynamicznie struktury pliku.

+0

Używaliśmy tego składnika również w naszej firmie. W oparciu o błędy w komponencie niektóre z naszych wyjątkowo obciążonych usług spowodowały wyjątek EngineException. Po otrzymaniu od Microsoft Support Bilet zdecydowaliśmy się przejść na SharpZLib. To było 2 lata temu. Nie wiem, jak dobry jest dzisiaj element? –

+0

Nigdy nie mieliśmy z tym żadnych problemów, ale jest używany w usługach eksportowych, które generalnie działają co godzinę, ale zazwyczaj codziennie.Szyfrowanie jest również przydatne pod numerem – Macros

20

jest do tego miły. Working example

Możesz zapisać kod pocztowy bezpośrednio w odpowiedzi.OutputStream. Kod wygląda następująco:

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 jest bezpłatny.

0

Tworzenie pliku ZIP "w locie" będzie wykonane przy użyciu naszego komponentu Rebex ZIP.

Poniższy przykład opisuje je w pełni, w tym tworzenie podfolder:

// 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

Jeśli używasz .NET Framework 4.5 lub nowszy cię może ominąć biblioteki innych firm i użyć macierzystej klasy System.IO.Compression.ZipArchive.

Oto krótki przykładowy kod przy użyciu MemoryStream i kilka tablicami bajtów reprezentującego dwa pliki:

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

Można go używać wewnątrz MVC Controller zwrócenie ActionResult: alternatywnie, jeśli trzeba phisically stworzyć archiwum zip, możesz albo zachować dysk MemoryStream lub całkowicie go zastąpić FileStream.

Aby uzyskać więcej informacji na ten temat, można również read this post.

Powiązane problemy