如何为 MemoryStream 中写入的内容提供 *.csv 扩展名?

问题描述

我正在开发一个 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);