【问题标题】:How can I give a *.csv extension to something written in a MemoryStream?如何为 MemoryStream 中编写的内容提供 *.csv 扩展名?
【发布时间】:2021-08-28 09:52:07
【问题描述】:

我正在开发一个 Azure 函数,用于从自定义对象列表创建 CSV 文件,将其压缩并使用以下代码将其上传到 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 的本地存储。你能帮帮我吗?

【问题讨论】:

  • “用提取器打开它”究竟是什么意思?没有“内部 CSV 文件”——只有数据。 GZip 没有任何指定嵌入数据中的文件名 - 它只是压缩数据本身。
  • @JonSkeet 是的,我知道......我试图用内存流来做这些事情。你说得对,我问是因为也许有办法克服这个问题。例如,我的意思是用 7z 打开。
  • “例如”,还是 7z?您是否尝试过(例如)gunzip?因为我希望它只是创建 test.csv。可能是因为 test.csv(以及 test.csv-1 和 test.csv-2)已经存在,所以创建了 7z 的 test.csv-3?
  • @JonSkeet 你是对的,因为 test.csv 已经存在,所以创建了 test.csv-* 文件。无论如何,如果我尝试解压缩存档,7z 会以错误结束。
  • 它是否适用于其他 .gz 文件?在这一点上,你的问题真的很令人困惑。

标签: c# csv azure-functions memorystream gzipstream


【解决方案1】:

关于问题,请参考以下代码

            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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-25
    • 1970-01-01
    • 1970-01-01
    • 2011-01-05
    • 2011-10-19
    • 1970-01-01
    • 2010-10-26
    • 1970-01-01
    相关资源
    最近更新 更多