Sie müssen einige Dateien dynamisch in eine ZIP-Datei packen, um ein SCORM-Paket zu erstellen. Wer weiß, wie dies mit Code gemacht werden kann? Ist es möglich, die Ordnerstruktur auch innerhalb der .zip dynamisch zu erstellen?Wie erstellt und füllt man eine ZIP-Datei mit ASP.NET?
Antwort
Sie müssen keine externe Bibliothek mehr verwenden. System.IO.Packaging verfügt über Klassen, die zum Löschen von Inhalt in eine Zip-Datei verwendet werden können. Es ist jedoch nicht einfach. Here's a blog post with an example (es ist am Ende; graben Sie dafür).
Der Link ist nicht stabil, also hier das Beispiel Jon in der Post zur Verfügung gestellt.
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;
}
}
}
}
Sie konnten einen Blick auf SharpZipLib nehmen. Und hier ist ein sample.
Beat mich dazu 15 Sekunden ... – JoshBerke
Ich habe eine kostenlose Komponente von chilkat für benutzte: http://www.chilkatsoft.com/zip-dotnet.asp. Es ist so ziemlich alles, was ich benötigt habe, aber ich bin mir nicht sicher, ob ich die Dateistruktur dynamisch erstellen soll.
Wir haben diese Komponente auch in unserer Firma verwendet. Aufgrund von Fehlern in der Komponente haben einige unserer extrem beanspruchten Dienste eine EngineException verursacht. Nach einem Microsoft Support Ticket haben wir uns für den Wechsel zu SharpZLib entschieden. Das war vor 2 Jahren. Ich weiß nicht, wie gut die Komponente heute ist? –
Wir hatten nie irgendwelche Probleme damit, aber es wird in Exportdiensten verwendet, die im Allgemeinen höchstens jede Stunde laufen, aber normalerweise täglich.Die Verschlüsselung ist auch nützlich – Macros
DotNetZip ist schön dafür. Working example
Sie können die Postleitzahl direkt in Response.OutputStream schreiben. Der Code sieht so aus:
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 ist kostenlos.
Erstellen von ZIP-Datei "on the fly" würde mit unserer Rebex ZIP Komponente erfolgen.
Das folgende Beispiel beschreibt es voll gebracht, darunter auch einen Unterordner:
// 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();
DotNetZip ist sehr einfach zu bedienen ... Creating Zip files in ASP.Net
Wenn Sie .NET Framework verwenden 4.5 oder neuer Sie können Bibliotheken von Drittanbietern umgehen und die native Klasse System.IO.Compression.ZipArchive
verwenden.
Hier ist ein schnelles Codebeispiel ein Memorystream und ein paar Byte-Arrays, die zwei Dateien mit:
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");
}
Sie können es in einem MVC-Controller verwenden Rückkehr eines ActionResult
: alternativ, wenn Sie erstellen, um phisically die Zip-Archiv, können Sie entweder die MemoryStream
auf Festplatte persistieren oder vollständig durch eine FileStream
ersetzen.
Für weitere Informationen zu diesem Thema auch read this post können.
Mögliches Duplikat [System.IO.Packaging Mit einer ZIP-Datei zu generieren] (http://stackoverflow.com/questions/6386113/using-system-io-packaging-to-generate-a-zip-file) – Will