245 lines
7.9 KiB
C#
245 lines
7.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.IO.Compression;
|
|
|
|
public static class Zip
|
|
{
|
|
// ============================================================
|
|
// UTILIDADES
|
|
// ============================================================
|
|
|
|
private static string CrearDirectorioTemporal()
|
|
{
|
|
string dir;
|
|
do
|
|
{
|
|
dir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
|
|
}
|
|
while (Directory.Exists(dir));
|
|
|
|
Directory.CreateDirectory(dir);
|
|
return dir;
|
|
}
|
|
|
|
private static void ObtenerFicherosRecursivo(string ruta, List<string> lista)
|
|
{
|
|
lista.AddRange(Directory.GetFiles(ruta));
|
|
|
|
foreach (var dir in Directory.GetDirectories(ruta))
|
|
{
|
|
ObtenerFicherosRecursivo(dir, lista);
|
|
}
|
|
}
|
|
|
|
// ============================================================
|
|
// EXTRACCIÓN
|
|
// ============================================================
|
|
|
|
public static void ExtraerArchivo(byte[] zipBytes, string nombreInterno, string destino)
|
|
{
|
|
using (var ms = new MemoryStream(zipBytes))
|
|
{
|
|
ExtraerArchivo(ms, nombreInterno, destino);
|
|
}
|
|
}
|
|
|
|
public static void ExtraerArchivo(Stream zipStream, string nombreInterno, string destino)
|
|
{
|
|
using (var zip = new ZipArchive(zipStream, ZipArchiveMode.Read, false))
|
|
{
|
|
var entry = zip.GetEntry(nombreInterno);
|
|
if (entry == null)
|
|
throw new FileNotFoundException("El archivo '" + nombreInterno + "' no existe dentro del ZIP.");
|
|
|
|
string dirTemp = CrearDirectorioTemporal();
|
|
string tempFile = Path.Combine(dirTemp, Path.GetFileName(nombreInterno));
|
|
|
|
entry.ExtractToFile(tempFile, true);
|
|
|
|
if (Directory.Exists(destino))
|
|
destino = Path.Combine(destino, Path.GetFileName(nombreInterno));
|
|
|
|
if (File.Exists(destino))
|
|
File.Delete(destino);
|
|
|
|
File.Move(tempFile, destino);
|
|
}
|
|
}
|
|
|
|
public static byte[] ExtraerArchivoABytes(byte[] zipBytes, string nombreInterno)
|
|
{
|
|
using (var ms = new MemoryStream(zipBytes))
|
|
{
|
|
return ExtraerArchivoABytes(ms, nombreInterno);
|
|
}
|
|
}
|
|
|
|
public static byte[] ExtraerArchivoABytes(Stream zipStream, string nombreInterno)
|
|
{
|
|
using (var zip = new ZipArchive(zipStream, ZipArchiveMode.Read, false))
|
|
{
|
|
var entry = zip.GetEntry(nombreInterno);
|
|
if (entry == null)
|
|
throw new FileNotFoundException("El archivo '" + nombreInterno + "' no existe dentro del ZIP.");
|
|
|
|
using (var entryStream = entry.Open())
|
|
using (var output = new MemoryStream())
|
|
{
|
|
entryStream.CopyTo(output);
|
|
return output.ToArray();
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void ExtraerArchivo(string zipPath, string nombreInterno, string destino)
|
|
{
|
|
using (var fs = File.OpenRead(zipPath))
|
|
{
|
|
ExtraerArchivo(fs, nombreInterno, destino);
|
|
}
|
|
}
|
|
|
|
public static void ExtraerTodo(string zipPath, string destino, bool eliminarDestino = false)
|
|
{
|
|
if (eliminarDestino && Directory.Exists(destino))
|
|
Directory.Delete(destino, true);
|
|
|
|
if (!Directory.Exists(destino))
|
|
Directory.CreateDirectory(destino);
|
|
|
|
// En netstandard2.0 solo está ExtractToDirectory(string, string)
|
|
ZipFile.ExtractToDirectory(zipPath, destino);
|
|
}
|
|
|
|
public static void ExtraerTodo(Stream zipStream, string destino, bool eliminarDestino = false)
|
|
{
|
|
if (eliminarDestino && Directory.Exists(destino))
|
|
Directory.Delete(destino, true);
|
|
|
|
if (!Directory.Exists(destino))
|
|
Directory.CreateDirectory(destino);
|
|
|
|
using (var zip = new ZipArchive(zipStream, ZipArchiveMode.Read, false))
|
|
{
|
|
foreach (var entry in zip.Entries)
|
|
{
|
|
string fullPath = Path.Combine(destino, entry.FullName);
|
|
|
|
string dir = Path.GetDirectoryName(fullPath);
|
|
if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir))
|
|
Directory.CreateDirectory(dir);
|
|
|
|
if (string.IsNullOrEmpty(entry.Name))
|
|
continue; // directorio
|
|
|
|
entry.ExtractToFile(fullPath, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
// ============================================================
|
|
// COMPRESIÓN
|
|
// ============================================================
|
|
|
|
public static byte[] ComprimirArchivos(Dictionary<string, byte[]> archivos)
|
|
{
|
|
// Crear un nombre de archivo temporal que NO exista
|
|
string tempFileName = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".zip");
|
|
|
|
using (ZipArchive zip = ZipFile.Open(tempFileName, ZipArchiveMode.Create))
|
|
{
|
|
foreach (var archivo in archivos)
|
|
{
|
|
var entry = zip.CreateEntry(archivo.Key, CompressionLevel.Optimal);
|
|
using (Stream stream = entry.Open())
|
|
{
|
|
byte[] data = archivo.Value;
|
|
stream.Write(data, 0, data.Length);
|
|
}
|
|
}
|
|
}
|
|
|
|
byte[] result = File.ReadAllBytes(tempFileName);
|
|
|
|
try { File.Delete(tempFileName); } catch { }
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
public static byte[] ComprimirArchivos(Dictionary<string, Stream> archivos)
|
|
{
|
|
string tempZip = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".zip");
|
|
|
|
using (var zip = ZipFile.Open(tempZip, ZipArchiveMode.Create))
|
|
{
|
|
foreach (var kv in archivos)
|
|
{
|
|
var entry = zip.CreateEntry(kv.Key, CompressionLevel.Optimal);
|
|
using (var entryStream = entry.Open())
|
|
{
|
|
kv.Value.CopyTo(entryStream);
|
|
}
|
|
}
|
|
}
|
|
|
|
byte[] resultado = File.ReadAllBytes(tempZip);
|
|
try { File.Delete(tempZip); } catch { }
|
|
return resultado;
|
|
}
|
|
|
|
// ============================================================
|
|
// AÑADIR ARCHIVOS (RECREANDO ZIP)
|
|
// ============================================================
|
|
|
|
public static void AñadirArchivo(string zipPath, string archivoOrigen, string nombreDestino)
|
|
{
|
|
string tempZip = Path.GetTempFileName();
|
|
|
|
using (var zipNuevo = ZipFile.Open(tempZip, ZipArchiveMode.Create))
|
|
{
|
|
if (File.Exists(zipPath))
|
|
{
|
|
using (var zipViejo = ZipFile.Open(zipPath, ZipArchiveMode.Read))
|
|
{
|
|
foreach (var entry in zipViejo.Entries)
|
|
{
|
|
if (entry.FullName.Equals(nombreDestino, StringComparison.OrdinalIgnoreCase))
|
|
continue;
|
|
|
|
var nueva = zipNuevo.CreateEntry(entry.FullName, CompressionLevel.Optimal);
|
|
using (var src = entry.Open())
|
|
using (var dst = nueva.Open())
|
|
{
|
|
src.CopyTo(dst);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var nuevo = zipNuevo.CreateEntry(nombreDestino, CompressionLevel.Optimal);
|
|
using (var origen = File.OpenRead(archivoOrigen))
|
|
using (var destino = nuevo.Open())
|
|
{
|
|
origen.CopyTo(destino);
|
|
}
|
|
}
|
|
|
|
File.Copy(tempZip, zipPath, true);
|
|
try { File.Delete(tempZip); } catch { }
|
|
}
|
|
|
|
// ============================================================
|
|
// COMPRIMIR DIRECTORIO
|
|
// ============================================================
|
|
|
|
public static void ComprimirDirectorio(string directorio, string zipPath)
|
|
{
|
|
if (File.Exists(zipPath))
|
|
File.Delete(zipPath);
|
|
|
|
ZipFile.CreateFromDirectory(directorio, zipPath, CompressionLevel.Optimal, false);
|
|
}
|
|
}
|