Membangun ZIP dalam memori berguna ketika Anda perlu untuk streaming sebuah download, mentransfer byte ke layanan lain, atau menyimpan sebuah arsip di database tanpa menyentuh cakera. Aspose.ZIP untuk .NET mendedahkan API yang bersih untuk membuat archive zip menggunakan streaming, pilih pengaturan kompresi, dan simpan hasilnya pada MemoryStream atau langsung ke respons HTTP.
Panduan ini menyediakan kode lengkap dan benar yang dapat Anda masukkan ke dalam aplikasi konsol atau proyek ASP.NET Core.
Persyaratan
- .NET 6 atau lebih baru
- Untuk NuGet:
Aspose.Zip
dotnet add package Aspose.Zip
Nama yang digunakan:
using Aspose.Zip; // Archive, ArchiveEntry
using Aspose.Zip.Saving; // DeflateCompressionSettings, CompressionLevel
Mulai Cepat: Buat ZIP sepenuhnya dalam memori
Contoh ini menambahkan entri dari string dan file pada cakera, menyimpan arsip ke MemoryStream, dan mendedahkan array byte yang dihasilkan.
// 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");
}
}
- Titik Kunci *
new Archive()Membuat ZIP kosong.CreateEntry(entryName, stream, entrySettings)Menambahkan file dari ** setiap aliran yang dapat dibaca**.archive.Save(stream)menulis arkib ke aliran yang Anda pilih (memori, jaringan, badan respons).
Tambah pohon folder penuh tanpa menulis file temp
Pergi direktori secara berulang, simpan jalur relatif, dan tulis arkib akhir ke ingatan.
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: streaming download ZIP tanpa cakera I/O
Titik akhir ini membangun ZIP dalam memori dari beberapa sumber dan mengembalikannya dengan jenis konten yang benar dan nama file download.
// 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();
“Mengapa saya di sini?”Minimum APIs membutuhkan beban pembayaran konkrit. untuk arsip yang sangat besar, lebih baik streaming langsung ke 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);
});
Pilih pengaturan kompresi
DeflateCompressionSettings Mengontrol kecepatan vs ukuran:
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
Lakukan pengaturan melalui new ArchiveEntrySettings(deflate) Anda dapat mencampur pengaturan per entri jika perlu.
Menambahkan entri dari aliran dengan aman
- Penggunaan
File.OpenRead(path)untuk mengalirkan file besar tanpa memuatnya sepenuhnya ke dalam memori. - Untuk konten yang dihasilkan, tulis ke a
MemoryStreamatau aPipeWriter- menyokong aliran dan mentransfer keCreateEntry. - Menyediakan aliran setelah setiap
CreateEntryMembebaskan sumber daya dengan cepat.
Contoh untuk konten besar yang dihasilkan:
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);
}
Validasi dan kesilapan pengendalian
- Periksa input yang ada sebelum ditambahkan ke arkib.
- Penciptaan di dalam
try/catchdan mengembalikan kesalahan HTTP yang jelas untuk web APIs. - Perbedaannya adalah dengan menghubungkan jalur ke depan (
/untuk perilaku yang konsisten di seluruh alat.
Performa Checklist
- Choose
CompressionLevel.LowUntuk download real-time ketika kecepatan lebih penting dari ukuran. - Hindari memuat entri besar sepenuhnya ke RAM; aliran dari file atau arus jaringan.
- Untuk file multi-GB yang sangat besar, streaming langsung ke
HttpResponse.Bodyatau aliran sasaran lain bukannya buffering. - Dispose
Archivedan semua input mengalir secara deterministik.
FAQ
**Bolehkah saya melindungi kata sandi dalam memori ZIP?**Aspose.ZIP mendukung file ZIP terenkripsi. TraditionalEncryptionSettings atau AesEncryptionSettings melalui ArchiveEntrySettingsPermohonan per entri saat panggilan CreateEntry.
**Bolehkah saya memperbarui ZIP yang ada yang saya muat ke dalam memori?**Ya, masukkan ke dalam sebuah Archivemenambahkan atau menghapus entri, kemudian Save Kembali ke aliran.
**Apakah ini bekerja di Azure App Service atau konten?**Ya. in-memory dan streaming zipping bekerja dengan baik di lingkungan sandboxed di mana akses cakera terbatas.
Kesimpulannya
Anda membuat arsip ZIP ** sepenuhnya dalam memori** dengan Aspose.ZIP untuk .NET, menambahkan entri dari aliran, menyesuaikan kompresi, dan mengembalikan arkib dari titik akhir ASP.NET Core tanpa file sementara.