[英]C# Asp.Net Create text file, zip it, and save to Blob - Without writing anything to disk
[英]Get byte array from .zip file in memory, without writing anything to disk
我正在嘗試獲取現有的.zip 文件(我從 api 作為字節數組獲取它),從中獲取一些文件,然后制作一個新的.zip 文件。 然后將 new.zip 文件作為字節數組返回。 問題是所有這些都應該在 memory 中完成,而不需要將任何實際文件寫入磁盤。
所以我有這個設置。 首先 memory stream 和 ziparchive 用於原始 zip 文件。 第二個 stream 和存檔表示第二個 zip,它將僅包含來自第一個 zip 的過濾項目。
using var downloadedRepoStream = new MemoryStream(binaryRepo);
using var downloadedRepoArchive = new ZipArchive(downloadedRepoStream, ZipArchiveMode.Read, true);
var entriesToExtract = downloadedRepoArchive.Entries; //add some filtering
using var subRepoStream = new MemoryStream();
using var subRepoArchive = new ZipArchive(subRepoStream, ZipArchiveMode.Create, true);
然后我通過每個條目 go 並將內容復制到第二個 zip。
foreach (var entry in entriesToExtract)
{
var entryName = entry.FullName.Split('/', 2)[1];
using var entryStream = entry.Open();
var subRepoEntry = subRepoArchive.CreateEntry(entry.FullName);
using var subRepoEntryStream = subRepoEntry.Open();
await entryStream.CopyToAsync(subRepoEntryStream);
}
最后,我需要將第二個 ziparchive 作為字節數組返回。 我以為我可以只調用 MemoryStream.ToArray(),但第二個 ZipArchive 使用的 MemoryStream 仍然是空的,盡管 ZipArchive 有文件。 那么如何從 ZipArchive 中獲取 byte[] 呢?
我能夠通過細微的調整獲得以下內容。 您似乎缺少設置 position 您希望從中開始閱讀的步驟:subRepoStream.Seek(0, SeekOrigin.Begin);
byte[] binaryRepo = ...
using MemoryStream downloadedRepoStream = new MemoryStream(binaryRepo);
using ZipArchive downloadedRepoArchive = new ZipArchive(downloadedRepoStream, ZipArchiveMode.Read, false);
ReadOnlyCollection<ZipArchiveEntry> entriesToExtract = downloadedRepoArchive.Entries; //add some filtering
using MemoryStream subRepoStream = new MemoryStream();
using ZipArchive subRepoArchive = new ZipArchive(subRepoStream, ZipArchiveMode.Create, false);
foreach (ZipArchiveEntry entry in entriesToExtract)
{
using Stream entryStream = entry.Open();
ZipArchiveEntry subRepoEntry = subRepoArchive.CreateEntry(entry.FullName);
using Stream subRepoEntryStream = subRepoEntry.Open();
await entryStream.CopyToAsync(subRepoEntryStream);
}
// before reading the stream you need to set the position to the beginning.
subRepoStream.Seek(0, SeekOrigin.Begin);
byte[] data = subRepoStream.ToArray();
問題是您在查看 stream 之前沒有關閉新的ZipArchive
。 您可以簡單地通過使用舊樣式using
block 來做到這一點
using var downloadedRepoStream = new MemoryStream(binaryRepo);
using var downloadedRepoArchive = new ZipArchive(downloadedRepoStream, ZipArchiveMode.Read, true);
var entriesToExtract = downloadedRepoArchive.Entries; //add some filtering
using var subRepoStream = new MemoryStream();
using (var subRepoArchive = new ZipArchive(subRepoStream, ZipArchiveMode.Create, true))
{
foreach (var entry in entriesToExtract)
{
var entryName = entry.FullName.Split('/', 2)[1];
using var entryStream = entry.Open();
var subRepoEntry = subRepoArchive.CreateEntry(entry.FullName);
using var subRepoEntryStream = subRepoEntry.Open();
await entryStream.CopyToAsync(subRepoEntryStream);
}
}
subRepoStream.Position = 0;
請注意, async
在使用MemoryStream
時沒有多大意義,因為無論如何它都是同步的。
遺憾的是ZipArchiveEntry
上沒有重命名功能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.