Actualmente estoy trabajando con SharpZipLib bajo .NET 2.0 y por medio de esto necesito para comprimir un archivo único de un solo archivo comprimido. Con el fin de hacer esto actualmente estoy usando lo siguiente:SharpZipLib: La compresión de un único archivo en un único archivo comprimido
string tempFilePath = @"C:\Users\Username\AppData\Local\Temp\tmp9AE0.tmp.xml";
string archiveFilePath = @"C:\Archive\Archive_[UTC TIMESTAMP].zip";
FileInfo inFileInfo = new FileInfo(tempFilePath);
ICSharpCode.SharpZipLib.Zip.FastZip fZip = new ICSharpCode.SharpZipLib.Zip.FastZip();
fZip.CreateZip(archiveFilePath, inFileInfo.Directory.FullName, false, inFileInfo.Name);
Esto funciona exactamente (más o menos) como debe ser, sin embargo, mientras que las pruebas que he encontrado un Gotcha menor. Digamos que mi directorio temporal (es decir, el directorio que contiene el archivo de entrada no comprimido) contiene los siguientes archivos:
tmp9AE0.tmp.xml //The input file I want to compress
xxx_tmp9AE0.tmp.xml // Some other file
yyy_tmp9AE0.tmp.xml // Some other file
wibble.dat // Some other file
Cuando ejecuto la compresión de todos los archivos .xml
están incluidas en el archivo comprimido. La razón de esto es debido al parámetro final fileFilter
pasado al método CreateZip
. Bajo el capó SharpZipLib está llevando a cabo una comparación de patrones y esto también recoge los archivos con el prefijo xxx_
y yyy_
. Supongo que también recogería cualquier cosa postfijada.
Entonces la pregunta es, ¿cómo puedo comprimir un archivo único con SharpZipLib? Entonces, de nuevo, tal vez la pregunta es cómo puedo formatear ese fileFilter
para que la coincidencia solo pueda recoger el archivo que quiero comprimir y nada más.
Como acotación al margen, ¿hay alguna razón de por qué no System.IO.Compression
incluyen una clase ZipStream
? (Sólo es compatible con GZipStream)
EDIT: Solución (Derivado de respuesta aceptada de Hans Passant)
Este es el método de compresión implementé:
private static void CompressFile(string inputPath, string outputPath)
{
FileInfo outFileInfo = new FileInfo(outputPath);
FileInfo inFileInfo = new FileInfo(inputPath);
// Create the output directory if it does not exist
if (!Directory.Exists(outFileInfo.Directory.FullName))
{
Directory.CreateDirectory(outFileInfo.Directory.FullName);
}
// Compress
using (FileStream fsOut = File.Create(outputPath))
{
using (ICSharpCode.SharpZipLib.Zip.ZipOutputStream zipStream = new ICSharpCode.SharpZipLib.Zip.ZipOutputStream(fsOut))
{
zipStream.SetLevel(3);
ICSharpCode.SharpZipLib.Zip.ZipEntry newEntry = new ICSharpCode.SharpZipLib.Zip.ZipEntry(inFileInfo.Name);
newEntry.DateTime = DateTime.UtcNow;
zipStream.PutNextEntry(newEntry);
byte[] buffer = new byte[4096];
using (FileStream streamReader = File.OpenRead(inputPath))
{
ICSharpCode.SharpZipLib.Core.StreamUtils.Copy(streamReader, zipStream, buffer);
}
zipStream.CloseEntry();
zipStream.IsStreamOwner = true;
zipStream.Close();
}
}
}
En cuanto a tu lado: ZipStream no tendría mucho sentido, ya que ZIP es un formato de archivo que puede contener más de un archivo. Supongo que podrían haber proporcionado una API completa para lectura y escritura y ZIP, pero obviamente habría sido mucho más esfuerzo que GZipStream. –
En un aparte de la mía, ya que sólo se está comprimiendo un solo archivo, hay una razón por la que no desea utilizar simplemente la compresión gzip, que, como se nota, cuenta con el apoyo en el marco? –
Me encantaría, podría hacer esto con un par de líneas de código. Tiene que ser postal como nuestra mesa de 'apoyo' no puede manejar las complejidades de gzip (hizo que el sonido sarcástico ??;)) – MrEyes