c# - descomprimir - system.io.compression vb.net example
recomendar una biblioteca/API para descomprimir un archivo en C# (12)
Parece que no hay biblioteca / API incorporada en C # para descomprimir un archivo zip. Estoy buscando una biblioteca / API gratuita (mejor de código abierto) que pueda funcionar con .Net 3.5 + VSTS 2008 + C # para descomprimir un archivo zip y extraer todos los archivos en una carpeta específica.
¿Alguna biblioteca / API recomendada o muestras?
Eche un vistazo a mi pequeña biblioteca: http://zipstorer.codeplex.com
En el pasado, he usado http://www.codeplex.com/DotNetZip (MS-PL), http://www.icsharpcode.net/OpenSource/SharpZipLib/ (GPL) y el 7ZIP SDK para C # (dominio público). Todos funcionan muy bien, y son de código abierto.
Elegiría DotNetZip en esta situación, y aquí hay un código de muestra de la página de ejemplos de C # :
using (ZipFile zip = ZipFile.Read(ExistingZipFile))
{
foreach (ZipEntry e in zip)
{
e.Extract(TargetDirectory);
}
}
La GPL
http://www.icsharpcode.net/OpenSource/SharpZipLib/
O el menos restrictivo Ms-PL
http://www.codeplex.com/DotNetZip
Para completar esta respuesta, el ZipPackage Framework tiene ZipPackage , tuve menos éxito con él.
Preferiría SharpZiplib. Encuentra el código de muestra para descomprimir archivos en .Net C #
Recomendaría nuestro http://www.rebex.net/zip.net/ pero soy parcial. Download versión de prueba y comprueba las características y las muestras tú mismo.
Si desea usar la compresión 7-zip, consulte el artículo EggheadCafe de Peter Bromberg. Cuidado: el código fuente LZMA para c # no tiene comentarios xml (en realidad, muy pocos comentarios).
Si no quiere usar un componente externo, aquí hay un código que desarrollé anoche usando la clase ZipPackage de .NET.
private static void Unzip()
{
var zipFilePath = "c://myfile.zip";
var tempFolderPath = "c://unzipped";
using (Package pkg = ZipPackage.Open(zipFilePath, FileMode.Open, FileAccess.Read))
{
foreach (PackagePart part in pkg.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))
{
CopyStream(source, File.OpenWrite(target));
}
}
}
}
private static void CopyStream(Stream input, Stream output)
{
byte[] buffer = new byte[4096];
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, read);
}
}
Cosas a tener en cuenta:
El archivo ZIP DEBE tener un archivo [Content_Types] .xml en su raíz. Esto no fue un problema para mis requisitos, ya que controlaré el ajuste de cualquier archivo ZIP que se extraiga a través de este código. Para obtener más información sobre el archivo [Content_Types] .xml, consulte: http://msdn.microsoft.com/en-us/magazine/cc163372.aspx Hay un archivo de ejemplo debajo de la figura 13 del artículo.
No he probado el método CopyStream para garantizar que se comporta correctamente, ya que originalmente desarrollé esto para .NET 4.0 utilizando el método Stream.CopyTo ().
DotNetZip es fácil de usar. Aquí hay una muestra de descomprimir
using (var zip = Ionic.Zip.ZipFile.Read("archive.zip"))
{
zip.ExtractAll("unpack-directory");
}
Si tiene necesidades más complejas, como si desea escoger y elegir qué entradas extraer, o si hay contraseñas, o si desea controlar las rutas de acceso de los archivos extraídos, etc. etc., hay muchas opciones . Verifique el archivo de ayuda para más ejemplos.
DotNetZip es gratuito y de código abierto.
SevenZipSharp es un envoltorio alrededor de 7z.dll y LZMA SDK, que es de código abierto y gratuito.
SevenZipCompressor compressor = new SevenZipCompressor();
compressor.CompressionLevel = CompressionLevel.Ultra;
compressor.CompressionMethod = CompressionMethod.Lzma;
compressor.CompressionMode = CompressionMode.Create;
compressor.CompressFiles(...);
Si todo lo que quiere hacer es descomprimir el contenido de un archivo en una carpeta y sabe que solo se ejecutará en Windows, puede usar el objeto Shell de Windows. He utilizado la dynamic
de Framework 4.0 en este ejemplo, pero puede lograr los mismos resultados utilizando Type.InvokeMember
.
dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
dynamic compressedFolderContents = shellApplication.NameSpace(sourceFile).Items;
dynamic destinationFolder = shellApplication.NameSpace(destinationPath);
destinationFolder.CopyHere(compressedFolderContents);
Puede usar FILEOP_FLAGS para controlar el comportamiento del método CopyHere
.
#region CreateZipFile
public void StartZip(string directory, string zipfile_path)
{
Label1.Text = "Please wait, taking backup";
#region Taking files from root Folder
string[] filenames = Directory.GetFiles(directory);
// path which the zip file built in
ZipOutputStream p = new ZipOutputStream(File.Create(zipfile_path));
foreach (string filename in filenames)
{
FileStream fs = File.OpenRead(filename);
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
ZipEntry entry = new ZipEntry(filename);
p.PutNextEntry(entry);
p.Write(buffer, 0 , buffer.Length);
fs.Close();
}
#endregion
string dirName= string.Empty;
#region Taking folders from root folder
DirectoryInfo[] DI = new DirectoryInfo(directory).GetDirectories("*.*", SearchOption.AllDirectories);
foreach (DirectoryInfo D1 in DI)
{
// the directory you need to zip
filenames = Directory.GetFiles(D1.FullName);
if (D1.ToString() == "backup")
{
filenames = null;
continue;
}
if (dirName == string.Empty)
{
if (D1.ToString() == "updates" || (D1.Parent).ToString() == "updates" || (D1.Parent).Parent.ToString() == "updates" || ((D1.Parent).Parent).Parent.ToString() == "updates" || (((D1.Parent).Parent).Parent).ToString() == "updates" || ((((D1.Parent).Parent).Parent)).ToString() == "updates")
{
dirName = D1.ToString();
filenames = null;
continue;
}
}
else
{
if (D1.ToString() == dirName) ;
}
foreach (string filename in filenames)
{
FileStream fs = File.OpenRead(filename);
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
ZipEntry entry = new ZipEntry(filename);
p.PutNextEntry(entry);
p.Write(buffer, 0, buffer.Length);
fs.Close();
}
filenames = null;
}
p.SetLevel(5);
p.Finish();
p.Close();
#endregion
}
#endregion
#region EXTRACT THE ZIP FILE
public bool UnZipFile(string InputPathOfZipFile, string FileName)
{
bool ret = true;
Label1.Text = "Please wait, extracting downloaded file";
string zipDirectory = string.Empty;
try
{
#region If Folder already exist Delete it
if (Directory.Exists(Server.MapPath("~/updates/" + FileName))) // server data field
{
String[] files = Directory.GetFiles(Server.MapPath("~/updates/" + FileName));//server data field
foreach (var file in files)
File.Delete(file);
Directory.Delete(Server.MapPath("~/updates/" + FileName), true);//server data field
}
#endregion
if (File.Exists(InputPathOfZipFile))
{
string baseDirectory = Path.GetDirectoryName(InputPathOfZipFile);
using (ZipInputStream ZipStream = new
ZipInputStream(File.OpenRead(InputPathOfZipFile)))
{
ZipEntry theEntry;
while ((theEntry = ZipStream.GetNextEntry()) != null)
{
if (theEntry.IsFile)
{
if (theEntry.Name != "")
{
string directoryName = theEntry.Name.Substring(theEntry.Name.IndexOf(FileName)); // server data field
string[] DirectorySplit = directoryName.Split(''//');
for (int i = 0; i < DirectorySplit.Length - 1; i++)
{
if (zipDirectory != null || zipDirectory != "")
zipDirectory = zipDirectory + @"/" + DirectorySplit[i];
else
zipDirectory = zipDirectory + DirectorySplit[i];
}
string first = Server.MapPath("~/updates") + @"/" + zipDirectory;
if (!Directory.Exists(first))
Directory.CreateDirectory(first);
string strNewFile = @"" + baseDirectory + @"/" + directoryName;
if (File.Exists(strNewFile))
{
continue;
}
zipDirectory = string.Empty;
using (FileStream streamWriter = File.Create(strNewFile))
{
int size = 2048;
byte[] data = new byte[2048];
while (true)
{
size = ZipStream.Read(data, 0, data.Length);
if (size > 0)
streamWriter.Write(data, 0, size);
else
break;
}
streamWriter.Close();
}
}
}
else if (theEntry.IsDirectory)
{
string strNewDirectory = @"" + baseDirectory + @"/" +
theEntry.Name;
if (!Directory.Exists(strNewDirectory))
{
Directory.CreateDirectory(strNewDirectory);
}
}
}
ZipStream.Close();
}
}
}
catch (Exception ex)
{
ret = false;
}
return ret;
}
#endregion