我需要通过HttpClient从S3下载照片,然后将其存档为zip而不压缩,并将存档发送给用户。但是,我无法将 zip 存储在 RAM 中,也无法创建临时文件,因为我需要创建非常大的档案(15-20 GB 的数据)。
我需要 C# ASP 解决方案。
我试过这个:
var response = HttpContext.Response;
response.ContentType = "application/octet-stream";
response.Headers.Add($"Content-Disposition", $"attachment; filename=\"ololo.zip\"");
await using var outputStream = response.Body;
using var zipStream = new ZipOutputStream(outputStream);
zipStream.SetLevel(9);
for (int i = 0; i < fileUrls.Count; i++)
{
var fileName = $"file{i + 1}.jpg";
var zipEntry = new ZipEntry(fileName);
zipStream.PutNextEntry(zipEntry);
using var httpClient = new HttpClient();
using var remoteStream = await httpClient.GetStreamAsync(fileUrls[i]);
await remoteStream.CopyToAsync(zipStream);
zipStream.CloseEntry();
}
zipStream.IsStreamOwner = false;
await zipStream.FinishAsync(default);
return new EmptyResult();
但是我在异步操作时遇到了错误。我尝试过这个:
[HttpPost]
public async Task Zip([FromBody] JsonToZipInput input)
{
Response.ContentType = "application/octet-stream";
Response.Headers.Add($"Content-Disposition", $"attachment; filename=\"{input.FileName}\"");
await Response.StartAsync();
using var zipArchive = new ZipArchive(Response.BodyWriter.AsStream(), ZipArchiveMode.Create);
foreach (var (key, value) in input.FilePathsToUrls)
{
var zipEntry = zipArchive.CreateEntry(key, CompressionLevel.Optimal);
await using var zipStream = zipEntry.Open();
await using var stream = await _httpClient.GetStreamAsync(value);
await stream.CopyToAsync(zipStream);
}
}
但它会将所有存档加载到 RAM 中。
你必须在这里自己动手。您需要遵循 PKWare 应用说明 以及 zip 规范。您可以查看 C 语言的 zipflow 来获取指导。或者您可以尝试将 zipflow 转换为 C#。 zipflow 流式传输 zip 文件,而无需将整个文件存储在内存或文件系统中。