问题描述
我正在开发一个 Azure 函数来从自定义对象列表创建一个 CSV 文件,使用以下代码对其进行 gzip 并上传到 Azure 存储容器:
var blobServiceClient = new BlobServiceClient("My connection string");
var containerClient = blobServiceClient.GetBlobContainerClient("My container name");
var config = new CsvConfiguration(CultureInfo.CurrentCulture) { Delimiter = ";",Encoding = Encoding.UTF8 };
var list = new List<FakeModel>
{
new FakeModel { Field1 = "A",Field2 = "B" },new FakeModel { Field1 = "C",Field2 = "D" }
};
await using var memoryStream1 = new MemoryStream();
await using var streamWriter = new StreamWriter(memoryStream1);
await using var csvWriter = new CsvWriter(streamWriter,config);
await csvWriter.WriteRecordsAsync(list);
await csvWriter.FlushAsync();
memoryStream1.Position = 0;
await using var memoryStream2 = new MemoryStream();
await using var zip = new GZipStream(memoryStream2,CompressionMode.Compress,true);
await memoryStream1.copyToAsync(zip);
memoryStream2.Position = 0;
var blockBlob = containerClient.GetBlockBlobClient("test.csv.gz");
await blockBlob.UploadAsync(memoryStream2);
它有效。当我从云端下载 gzip 进行检查时,显然我知道该文件具有正确的名称,因此它显示为名称为 test.csv.gz
的 GZ 文件,但是当我下载它并使用提取器打开它时,我发现其中的 CSV 文件很奇怪,例如 test.csv-3
,我的计算机无法打开。当然,我需要它是一个有效的 *.csv
文件。这里的问题是使用内存流我只能为 blob 命名,而不是为内部 CSV 文件命名。我该怎么做?请记住,我希望使用内存流来简化 Azure Functions 的本地存储。你能帮我吗?
解决方法
关于问题,请参考以下代码
var blobServiceClient = new BlobServiceClient("My connection string");
var containerClient = blobServiceClient.GetBlobContainerClient("My container name");
var config = new CsvConfiguration(CultureInfo.CurrentCulture) { Delimiter = ";",Encoding = Encoding.UTF8 };
var list = new List<FakeModel>
{
new FakeModel { Field1 = "A",Field2 = "B" },new FakeModel { Field1 = "C",Field2 = "D" }
};
await using var memoryStream1 = new MemoryStream();
await using var streamWriter = new StreamWriter(memoryStream1);
await using var csvWriter = new CsvWriter(streamWriter,config);
await csvWriter.WriteRecordsAsync(list);
await csvWriter.FlushAsync();
memoryStream1.Position = 0;
var options = new BlockBlobOpenWriteOptions
{
HttpHeaders = new BlobHttpHeaders
{
ContentType = "application/gzip",},};
await using var outStream= await containerClient.GetBlockBlobClient("test.csv.gz").OpenWriteAsync(true,options);
await using var zip = new GZipStream(outStream,CompressionMode.Compress,true);
await memoryStream1.CopyToAsync(zip);
await using var input = await containerClient.GetBlockBlobClient("test.csv.gz").OpenReadAsync();
await using var file = File.Create("<file path>");
await using var zip1 = new GZipStream(input,CompressionMode.Decompress,true);
await zip1.CopyToAsync(file);