Files
tsZIP.NS/Zip.cs
2026-05-14 15:43:36 +02:00

241 lines
7.8 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)
{
string tempZip = Path.GetTempFileName();
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())
{
byte[] data = kv.Value;
entryStream.Write(data, 0, data.Length);
}
}
}
byte[] resultado = File.ReadAllBytes(tempZip);
try { File.Delete(tempZip); } catch { }
return resultado;
}
public static byte[] ComprimirArchivos(Dictionary<string, Stream> archivos)
{
string tempZip = Path.GetTempFileName();
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);
}
}