如何在不写入文件的情况下压缩流并将其上传到 Azure Blob 存储?
Posted
技术标签:
【中文标题】如何在不写入文件的情况下压缩流并将其上传到 Azure Blob 存储?【英文标题】:How do you compress a stream and upload it to Azure Blob Storage without writing to a file? 【发布时间】:2021-06-03 16:33:35 【问题描述】:我在 ASP.NET Core 中编写了一个 Post
方法来压缩请求正文并将其上传到 Azure Blob 存储。该方法接受参数如下:
public async Task<IActionResult> Post([FromHeader] string AssignmentId)
然后设置各种字符串,包括获取存储的连接字符串:
string fileName = $"AssignmentId.gz";
string compressedFilePath = Path.Combine(hostEnvironment.ContentRootPath, $"Test JSONs/fileName");
string connectionString = Environment.GetEnvironmentVariable("AZURE_STORAGE_CONNECTION_STRING");
我初始化BlobClient
:
BlobClient blobClient = new BlobClient(connectionString, "assignments", fileName);
然后我创建一个文件,并使用GZipStream
将请求的正文流压缩到文件中:
using (FileStream compressedFileStream = System.IO.File.Create(compressedFilePath))
using GZipStream compressionStream = new GZipStream(compressedFileStream, CompressionMode.Compress);
using Stream bodyStream = HttpContext.Request.Body;
await bodyStream.CopyToAsync(compressionStream);
最后我阅读了我刚刚编写的文件并使用FileStream
上传:
using (FileStream fileStream = System.IO.File.OpenRead(compressedFilePath))
await blobClient.UploadAsync(fileStream);
这个解决方案有效,但我担心文件的不断读写,就速度而言。我尝试使用传递给GZipStream
的MemoryStream
,但是当文件应该为1KB+ 时,它最终只上传了10B 文件。
感谢任何建议。
这里是完整的方法:
public async Task<IActionResult> Post([FromHeader] string AssignmentId)
string fileName = $"AssignmentId.gz";
string compressedFilePath = Path.Combine(hostEnvironment.ContentRootPath, $"Test JSONs/fileName");
string connectionString = Environment.GetEnvironmentVariable("AZURE_STORAGE_CONNECTION_STRING");
BlobClient blobClient = new BlobClient(connectionString, "assignments", fileName);
using (FileStream compressedFileStream = System.IO.File.Create(compressedFilePath))
using GZipStream compressionStream = new GZipStream(compressedFileStream, CompressionMode.Compress);
using Stream bodyStream = HttpContext.Request.Body;
await bodyStream.CopyToAsync(compressionStream);
using (FileStream fileStream = System.IO.File.OpenRead(compressedFilePath))
await blobClient.UploadAsync(fileStream);
return Ok();
【问题讨论】:
除了 BLOB 存储上传之外,它实际上是一个副本:***.com/questions/10599596/… @MitchWheat 该问题的答案在压缩流上使用 .Close() ,但是当我使用它时,它也会关闭传递到压缩流中的 MemoryStream。 ***.com/questions/63623674/… 【参考方案1】:我最终解决了这个问题,既让压缩流保持打开状态,又通过重置压缩流正在写入的内存流的位置(感谢@MitchWheat!)。
using MemoryStream memoryStream = new MemoryStream() ;
using (Stream bodyStream = HttpContext.Request.Body)
using (GZipStream compressionStream = new GZipStream(memoryStream,
CompressionMode.Compress, true))
await bodyStream.CopyToAsync(compressionStream);
memoryStream.Position = 0;
await blobClient.UploadAsync(memoryStream, overwrite: true);
【讨论】:
以上是关于如何在不写入文件的情况下压缩流并将其上传到 Azure Blob 存储?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不使用 map reduce 的情况下使用 lzo 压缩写入 hadoop hdfs
如何在不包含节点模块文件夹的情况下将我的 React 项目上传到 GitHub [重复]