Construire un ZIP dans la mémoire est utile lorsque vous avez besoin de diffuser un téléchargement, de transférer des bytes à un autre service, ou de stocker un archive dans une base de données sans toucher le disque. Aspose.ZIP pour .NET expose une API propre pour créer des archives Zip en utilisant des flux, choisissez les paramètres de compression et sauvegardez le résultat dans un MemoryStream
ou directement à la réponse HTTP.
Ce guide fournit un code complet et correct que vous pouvez ajouter à une application de console ou à un projet ASP.NET Core.
Principaux
- .NET 6 ou plus tard
- Nouveau :
Aspose.Zip
dotnet add package Aspose.Zip
Les noms utilisés :
using Aspose.Zip; // Archive, ArchiveEntry
using Aspose.Zip.Saving; // DeflateCompressionSettings, CompressionLevel
Démarrage rapide : créer un ZIP entièrement dans la mémoire
Cet exemple ajoute des entrées d’une ligne et un fichier sur le disque, sauvegarde l’archive à un MemoryStream
et expose l’array de byte résultant.
// 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");
}
}
- Les points clés *
new Archive()
Créer un ZIP vide.CreateEntry(entryName, stream, entrySettings)
Ajouter un fichier à partir de ** tout flux lisible**.archive.Save(stream)
écrire l’archive à votre courant choisi (mémorisation, réseau, corps de réponse).
Ajouter un arbre entier sans écrire des fichiers temp
Walk a directory recursivement, préserver les voies relatives, et écrire l’archive finale à la mémoire.
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 : téléchargement ZIP sans disque I/O
Ce point de fin construit un ZIP dans la mémoire à partir de plusieurs sources et le retourne avec le type de contenu correct et un nom de fichier téléchargé.
// 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();
** Pourquoi ToArray() ici ?**Les APIs minimales nécessitent une charge de paiement concrète. Pour les archives très grandes, préférez le streaming directement à 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);
});
Choisissez les paramètres de compression
DeflateCompressionSettings
Contrôle de vitesse vs taille :
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
Passez les paramètres via new ArchiveEntrySettings(deflate)
Lorsque vous créez des entrées, vous pouvez mélanger les paramètres par entrée si nécessaire.
Ajoutez les entrées des courants en toute sécurité
- Utiliser
File.OpenRead(path)
Pour diffuser de grands fichiers sans les charger complètement dans la mémoire. - Pour le contenu généré, écrivez à un
MemoryStream
ou aPipeWriter
- soutenir le courant et le transférer àCreateEntry
. - Il y a des flux après chaque
CreateEntry
Les ressources gratuites rapidement.
Exemple de contenu généré :
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);
}
Validation et traitement d’erreurs
- Vérifiez les entrées existantes avant d’ajouter à l’archive.
- Création dans la
try/catch
et retourner une erreur HTTP claire pour les APIs Web. - Résultats de l’inscription avec des traces d’entrée (
/
Pour un comportement cohérent partout dans les outils.
Liste de contrôle des performances
- Choose
CompressionLevel.Low
Pour les téléchargements en temps réel lorsque la vitesse compte plus que la taille. - Évitez de charger des entrées massives complètement dans la RAM; le courant des fichiers ou des courants réseau.
- Pour les archives multi-GB très grandes, en streaming directement à
HttpResponse.Body
ou un autre flux cible au lieu de buffler. - Dispose
Archive
Toutes les entrées sont déterministes.
FAQ
** Puis-je protéger le mot de passe dans la mémoire ZIP ?**Aspose.ZIP soutient les archives ZIP cryptées. TraditionalEncryptionSettings
ou AesEncryptionSettings
via ArchiveEntrySettings
Appliquer par entrée lors de l’appel CreateEntry
.
** Puis-je mettre à jour un ZIP existant que j’ai chargé dans la mémoire ?**Oui, il faut le charger dans un Archive
ajouter ou supprimer les entrées, puis Save
Retour à un courant.
** Cela fonctionne-t-il dans Azure App Service ou dans les conteneurs ?**Oui. In-mémory et streaming zipping fonctionne bien dans les environnements sandboxed où l’accès au disque est limité.
Résumé
Vous avez créé un fichier ZIP totalement en mémoire avec Aspose.ZIP pour .NET, ajouté les entrées des courants, ajusté la compression, et retourné l’archive d’un point de fin ASP.NET Core sans fichiers temporaires.