c# - framework - system.io.compression vb.net example
¿Cómo puedo ZIP un archivo en C#, sin API de terceros? (7)
¿Cómo puedo programar (C #) ZIP un archivo (en Windows) sin utilizar ninguna biblioteca de terceros?
Si usa el Framework 4.5+, ahora están las clases ZipFile y ZipFile .
using (ZipArchive zip = ZipFile.Open("test.zip", ZipArchiveMode.Create))
{
zip.CreateEntryFromFile(@"c:/something.txt", "data/path/something.txt");
}
Necesita agregar referencias a:
- System.IO.Compression
- System.IO.Compression.FileSystem
Para .NET Core targeting net46, necesita agregar dependencias para
- System.IO.Compression
- System.IO.Compression.ZipFile
Ejemplo project.json:
"dependencies": {
"System.IO.Compression": "4.1.0",
"System.IO.Compression.ZipFile": "4.0.1"
},
"frameworks": {
"net46": {}
}
Para .NET Core 2.0, solo es necesario agregar una declaración de uso simple:
- utilizando System.IO.Compression;
Estoy bastante seguro de que esto no es un duplicado, así que tengan paciencia conmigo por solo un minuto.
¿Cómo puedo programar (C #) ZIP un archivo (en Windows) sin utilizar ninguna biblioteca de terceros? Necesito una llamada de Windows nativa o algo así; Realmente no me gusta la idea de comenzar un proceso, pero lo haré si es absolutamente necesario. Una llamada PInovke sería mucho mejor.
De lo contrario, permítame decirle lo que realmente estoy tratando de lograr: necesito la capacidad de permitir que un usuario descargue una colección de documentos en una sola solicitud. ¿Alguna idea sobre cómo lograr esto?
Basado en la respuesta de Simon McKenzie a esta pregunta , sugiero usar un par de métodos como este:
public static void ZipFolder(string sourceFolder, string zipFile)
{
if (!System.IO.Directory.Exists(sourceFolder))
throw new ArgumentException("sourceDirectory");
byte[] zipHeader = new byte[] { 80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
using (System.IO.FileStream fs = System.IO.File.Create(zipFile))
{
fs.Write(zipHeader, 0, zipHeader.Length);
}
dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
dynamic source = shellApplication.NameSpace(sourceFolder);
dynamic destination = shellApplication.NameSpace(zipFile);
destination.CopyHere(source.Items(), 20);
}
public static void UnzipFile(string zipFile, string targetFolder)
{
if (!System.IO.Directory.Exists(targetFolder))
System.IO.Directory.CreateDirectory(targetFolder);
dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
dynamic compressedFolderContents = shellApplication.NameSpace(zipFile).Items;
dynamic destinationFolder = shellApplication.NameSpace(targetFolder);
destinationFolder.CopyHere(compressedFolderContents);
}
}
Estaba en la misma situación, queriendo .NET en lugar de una biblioteca de terceros. Como otro cartel mencionado anteriormente, simplemente usar la clase ZipPackage (introducido en .NET 3.5) no es suficiente. Hay un archivo adicional que DEBE incluirse en el archivo para que el ZipPackage funcione. Si se agrega este archivo, el paquete ZIP resultante se puede abrir directamente desde el Explorador de Windows, no hay problema.
Todo lo que tiene que hacer es agregar el archivo [Content_Types] .xml a la raíz del archivo con un nodo "Predeterminado" para cada extensión de archivo que desee incluir. Una vez agregado, podría examinar el paquete desde el Explorador de Windows o descomprimir y leer sus contenidos mediante programación.
Puede encontrar más información sobre el archivo [Content_Types] .xml aquí: http://msdn.microsoft.com/en-us/magazine/cc163372.aspx
Aquí hay una muestra del archivo [Content_Types] .xml (debe nombrarse exactamente):
<?xml version="1.0" encoding="utf-8" ?>
<Types xmlns=
"http://schemas.openxmlformats.org/package/2006/content-types">
<Default Extension="xml" ContentType="text/xml" />
<Default Extension="htm" ContentType="text/html" />
<Default Extension="html" ContentType="text/html" />
<Default Extension="rels" ContentType=
"application/vnd.openxmlformats-package.relationships+xml" />
<Default Extension="jpg" ContentType="image/jpeg" />
<Default Extension="png" ContentType="image/png" />
<Default Extension="css" ContentType="text/css" />
</Types>
Y el C # para crear un archivo ZIP:
var zipFilePath = "c://myfile.zip";
var tempFolderPath = "c://unzipped";
using (Package package = ZipPackage.Open(zipFilePath, FileMode.Open, FileAccess.Read))
{
foreach (PackagePart part in package.GetParts())
{
var target = Path.GetFullPath(Path.Combine(tempFolderPath, part.Uri.OriginalString.TrimStart(''/'')));
var targetDir = target.Remove(target.LastIndexOf(''//'));
if (!Directory.Exists(targetDir))
Directory.CreateDirectory(targetDir);
using (Stream source = part.GetStream(FileMode.Open, FileAccess.Read))
{
source.CopyTo(File.OpenWrite(target));
}
}
}
Nota:
- Este código utiliza el método Stream.CopyTo en .NET 4.0
- Esto será mucho más simple con la introducción de la clase ZipArchive en .NET 4.5: http://msdn.microsoft.com/en-us/library/system.io.compression.ziparchive(v=vs.110).aspx
Para una aplicación .NET 2.0 utilicé SharpZipLib . Fácil de usar y de código abierto.
Parece que Windows podría dejarte hacer this ...
Lamentablemente, no creo que vayas a mover un proceso por separado a menos que vayas a un componente de un tercero.
¿Estás usando .NET 3.5? Puede usar la clase ZipPackage
y las clases relacionadas. Es más que simplemente descomprimir una lista de archivos porque quiere un tipo MIME para cada archivo que agregue. Puede hacer lo que quieras.
Actualmente estoy usando estas clases para un problema similar para archivar varios archivos relacionados en un único archivo para descargar. Usamos una extensión de archivo para asociar el archivo de descarga con nuestra aplicación de escritorio. Un pequeño problema que encontramos fue que no es posible usar una herramienta de terceros como 7-zip para crear los archivos zip porque el código del lado del cliente no puede abrirlo. ZipPackage agrega un archivo oculto que describe el tipo de contenido de cada archivo de componente y no puede abrir un archivo zip si falta ese archivo de tipo de contenido.
private static string CompressFile(string sourceFileName)
{
using (ZipArchive archive = ZipFile.Open(Path.ChangeExtension(sourceFileName, ".zip"), ZipArchiveMode.Create))
{
archive.CreateEntryFromFile(sourceFileName, Path.GetFileName(sourceFileName));
}
return Path.ChangeExtension(sourceFileName, ".zip");
}