Construcția unui ZIP în memorie este utilă atunci când trebuie să difuzezi o descărcare, să transferați byte la un alt serviciu sau să stocați un arhiv într-o bază de date fără a atinge discul. Aspose.ZIP pentru .NET expune o API curată pentru a crea arhive zIP folosind fluxuri, alegeți setările de compresie și salvați rezultatul pe un MemoryStream
sau direct la răspunsul HTTP.
Acest ghid oferă cod complet, corect pe care îl puteți introduce într-o aplicație de console sau un proiect ASP.NET Core.
Prevederile
- .NET 6 sau mai târziu
- Încă nu:
Aspose.Zip
dotnet add package Aspose.Zip
Numele spațiilor utilizate:
using Aspose.Zip; // Archive, ArchiveEntry
using Aspose.Zip.Saving; // DeflateCompressionSettings, CompressionLevel
Start rapid: creați un ZIP complet în memorie
Acest exemplu adaugă intrări dintr-o stringă și un fișier pe disc, salvează arhiva la un MemoryStream
, și expune aria de byte rezultată.
// File: Program.cs
using System;
using System.IO;
using System.Text;
using Aspose.Zip;
using Aspose.Zip.Saving;
class Program
{
static void Main()
{
// Prepare output buffer
using var zipBuffer = new MemoryStream();
// Choose compression (Deflate is the standard ZIP method)
var deflate = new DeflateCompressionSettings(CompressionLevel.Normal);
var entrySettings = new ArchiveEntrySettings(deflate);
using (var archive = new Archive())
{
// 1) Add a text file from memory
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("Hello from Aspose.ZIP in memory.")))
{
archive.CreateEntry("docs/readme.txt", ms, entrySettings);
}
// 2) Add a file from disk (streamed; not fully loaded in RAM)
var sourcePath = "report.pdf"; // ensure it exists
if (File.Exists(sourcePath))
{
using var fs = File.OpenRead(sourcePath);
archive.CreateEntry("reports/2025/report.pdf", fs, entrySettings);
}
// 3) Save the ZIP to our in-memory buffer
archive.Save(zipBuffer);
}
// Use the ZIP bytes as needed (send over network, write to DB, etc.)
byte[] zipBytes = zipBuffer.ToArray();
Console.WriteLine($"ZIP size: {zipBytes.Length} bytes");
}
}
- puncte cheie *
new Archive()
Creează un ZIP gol.CreateEntry(entryName, stream, entrySettings)
Adăugați un fișier de la ** orice flux citit**.archive.Save(stream)
scrie arhiva la fluxul ales (memorie, rețea, corpul de răspuns).
Adăugați un copac complet fără a scrie fișiere temp
Urmăriți un director recursiv, păstrați căile relative și scrieți arhiva finală în memorie.
using System.IO;
using Aspose.Zip;
using Aspose.Zip.Saving;
static class InMemoryZipper
{
public static byte[] ZipFolderToBytes(string sourceFolder, CompressionLevel level = CompressionLevel.Normal)
{
if (!Directory.Exists(sourceFolder))
throw new DirectoryNotFoundException(sourceFolder);
var deflate = new DeflateCompressionSettings(level);
var entrySettings = new ArchiveEntrySettings(deflate);
using var buffer = new MemoryStream();
using (var archive = new Archive())
{
var root = Path.GetFullPath(sourceFolder);
foreach (var filePath in Directory.GetFiles(root, "*", SearchOption.AllDirectories))
{
var rel = Path.GetRelativePath(root, filePath).Replace(Path.DirectorySeparatorChar, '/');
using var fs = File.OpenRead(filePath);
archive.CreateEntry(rel, fs, entrySettings);
}
archive.Save(buffer);
}
return buffer.ToArray();
}
}
ASP.NET Core: transmiterea unei descărcări ZIP fără disc I/O
Acest punct final construiește un ZIP în memorie din mai multe surse și îl întoarce cu tipul corect de conținut și un nume de fișier de descărcare.
// File: Program.cs (minimal API)
using System.Text;
using Aspose.Zip;
using Aspose.Zip.Saving;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/download-zip", () =>
{
using var buffer = new MemoryStream();
var deflate = new DeflateCompressionSettings(CompressionLevel.Normal);
var settings = new ArchiveEntrySettings(deflate);
using (var archive = new Archive())
{
// Add dynamic content (for example, a CSV generated on the fly)
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("id,name\n1,Alice\n2,Bob\n")))
archive.CreateEntry("data/users.csv", ms, settings);
// Add a static file from disk if available
var logo = "wwwroot/logo.png";
if (File.Exists(logo))
{
using var fs = File.OpenRead(logo);
archive.CreateEntry("assets/logo.png", fs, settings);
}
archive.Save(buffer);
}
buffer.Position = 0; // rewind for reading
return Results.File(
fileContents: buffer.ToArray(),
contentType: "application/zip",
fileDownloadName: $"bundle-{DateTime.UtcNow:yyyyMMdd-HHmmss}.zip");
});
app.Run();
- De ce nu e aici? *API-urile minime necesită o sarcină concreta. pentru arhive foarte mari, preferați streaming direct la
HttpResponse.Body
:
app.MapGet("/stream-zip", async (HttpContext ctx) =>
{
ctx.Response.ContentType = "application/zip";
ctx.Response.Headers.ContentDisposition = $"attachment; filename=\"bundle.zip\"";
var deflate = new DeflateCompressionSettings(CompressionLevel.Normal);
var settings = new ArchiveEntrySettings(deflate);
using var archive = new Archive();
// Add entries...
using var ms = new MemoryStream(Encoding.UTF8.GetBytes("hello"));
archive.CreateEntry("hello.txt", ms, settings);
// Stream directly to the client without buffering full ZIP in RAM
await archive.SaveAsync(ctx.Response.Body);
});
Selectați setările de compresie
DeflateCompressionSettings
Controlul vitezei vs dimensiune:
var fastest = new DeflateCompressionSettings(CompressionLevel.Low); // fastest, larger files
var balanced = new DeflateCompressionSettings(CompressionLevel.Normal); // default balance
var smallest = new DeflateCompressionSettings(CompressionLevel.High); // slowest, smallest files
Urmăriți setările prin new ArchiveEntrySettings(deflate)
atunci când creați intrări. puteți amesteca setările pe intrare dacă este necesar.
Adăugați intrări din fluxuri în condiții de siguranță
- Utilizarea
File.OpenRead(path)
să transmită fișierele mari fără a le încărca complet în memorie. - Pentru conținutul generat, scrieți la un
MemoryStream
sau aPipeWriter
- susține fluxul și trece laCreateEntry
. - Dispunem de fluxuri după fiecare
CreateEntry
pentru a elibera rapid resursele.
Exemple pentru conținut generat mare:
using System.IO;
using Aspose.Zip;
using Aspose.Zip.Saving;
static void AddLargeGeneratedEntry(Archive archive, string name)
{
// simulate a big stream produced incrementally
using var temp = new FileStream(Path.GetTempFileName(), FileMode.Create, FileAccess.ReadWrite, FileShare.None, 81920, FileOptions.DeleteOnClose);
using var writer = new StreamWriter(temp);
for (int i = 0; i < 200_000; i++) writer.WriteLine($"row-{i},value-{i}");
writer.Flush();
temp.Position = 0;
var settings = new ArchiveEntrySettings(new DeflateCompressionSettings(CompressionLevel.Normal));
archive.CreateEntry(name, temp, settings);
}
Validarea și gestionarea erorilor
- Verificați intrările existente înainte de a adăuga în arhivă.
- Creaţie în
try/catch
și returnarea unei erori HTTP clare pentru API-urile web. - Calea de intrare normalizată cu slash-uri înainte (
/
pentru un comportament consecvent pe tot parcursul instrumentelor.
Lista de verificare a performanței
- Choose
CompressionLevel.Low
pentru descărcările în timp real când viteza contează mai mult decât dimensiunea. - Evitați încărcarea intrărilor masive pe deplin în RAM; fluxul de la fișiere sau de rețea.
- Pentru fișierele multi-GB foarte mari, flux direct la
HttpResponse.Body
sau un alt flux țintă în loc de buffering. - Dispose
Archive
Toate intrările sunt deterministe.
FAQ
** Pot proteja parola in-memory ZIP?**Aspose.ZIP susține arhivele ZIP criptate. TraditionalEncryptionSettings
sau AesEncryptionSettings
prin ArchiveEntrySettings
Aplicarea prin intrare la apel CreateEntry
.
** Pot să actualizez un ZIP existent pe care l-am încărcat în memorie?**Da. încărcați-l într-o Archive
, adăugați sau ștergeți intrări, apoi Save
Înapoi la un flux.
**Acest lucru funcționează în Azure App Service sau în containere?**Da. In-memory și streamed zipping funcționează bine în mediile cu sandbox unde accesul la disc este limitat.
Rezumatul
Ați creat un arhiv ZIP în întregime în memorie cu Aspose.ZIP pentru .NET, ați adăugat intrări de la fluxuri, compresia ajustată și arhiva a fost returnată dintr-un punct final ASP.NET Core fără fișiere temporare.