1.在 .NET Core 中,结合 System.IO.Compression 命名空间和 System.IO 命名空间中的 FileStream 类、ZipFile 类可以实现将多个文件流压缩成一个 zip 文件流的功能。具体实现如下:
public async Task<FileViewDto> ExportUploadFileZipAsync(List<long> ids)
{
var streams = new Dictionary<string, Stream>();
foreach (var id in ids)
{
var data = await ExportUploadFileAsync(id);
string fileName = System.IO.Path.GetFileNameWithoutExtension(data.Name);
string extension = System.IO.Path.GetExtension(data.Name);
Stream stream = new MemoryStream(data.Content);
streams.Add($"{fileName}_{DateTime.UtcNow.AddHours(8).ToString("yyyyMMddHHmmssfff")}{extension}", stream);
}
byte[] fileBytes = CompressStreamsToZip(streams);
return new FileViewDto
{
Name = $"{DateTime.UtcNow.AddHours(8).ToString("yyyyMMddHHmmss")}.zip",
Content = fileBytes,
ContentType = "application/zip"
};
}
private byte[] CompressStreamsToZip(IDictionary<string, Stream> streams)
{
var zipStream = new MemoryStream();
try
{
using (var zipArchive = new ZipArchive(zipStream, ZipArchiveMode.Create, true))
{
foreach (var kvp in streams)
{
var entry = zipArchive.CreateEntry(kvp.Key);
using (var entryStream = entry.Open())
{
kvp.Value.CopyTo(entryStream);
}
}
}
zipStream.Seek(0, SeekOrigin.Begin);
}
catch (Exception ex)
{
_logger.LogError($"压缩文件出错,错误信息:{ex.Message}");
}
return zipStream.ToArray();
}
2.第二种方法
public byte[] ConvertZipStream(Dictionary<string, Stream> streams)
{
byte[] buffer = new byte[6500];
MemoryStream returnStream = new MemoryStream();
var zipMs = new MemoryStream();
using (ICSharpCode.SharpZipLib.Zip.ZipOutputStream zipStream = new ICSharpCode.SharpZipLib.Zip.ZipOutputStream(zipMs))
{
zipStream.SetLevel(9);
foreach (var kv in streams)
{
string fileName = kv.Key;
using (var streamInput = kv.Value)
{
ICSharpCode.SharpZipLib.Zip.ZipEntry zipEntry = new ICSharpCode.SharpZipLib.Zip.ZipEntry(fileName);
zipEntry.IsUnicodeText = true;
zipStream.PutNextEntry(zipEntry);
while (true)
{
var readCount = streamInput.Read(buffer, 0, buffer.Length);
if (readCount > 0)
{
zipStream.Write(buffer, 0, readCount);
}
else
{
break;
}
}
zipStream.Flush();
}
}
zipStream.Finish();
zipMs.Position = 0;
zipMs.CopyTo(returnStream, 5600);
}
returnStream.Position = 0;
byte[] returnBytes = new byte[returnStream.Length];
returnStream.Read(returnBytes, 0, returnBytes.Length);
returnStream.Seek(0, SeekOrigin.Begin);
return returnBytes;
}
var streams = new Dictionary<string, Stream>();
byte[] fileBytes = ConvertZipStream(streams);