【问题标题】:gzipstream memory stream to filegzipstream 内存流到文件
【发布时间】:2016-05-09 14:11:09
【问题描述】:

我正在尝试使用 Gzip 压缩压缩 JSON 文件以发送到另一个位置。它每天需要处理 5,000 - 10,000 个文件,我不需要本地机器上文件的压缩版本(它们实际上是被传输到 AWS S3 以进行长期归档)。

由于我不需要它们,我正在尝试压缩到内存流,然后使用它来写入 AWS,而不是将每个压缩到磁盘。每当我尝试这样做时,文件都会损坏(例如,当我在 7-Zip 中打开它们并尝试打开其中的 JSON 文件时,我会收到“数据错误文件损坏)。

当我尝试将内存流写入本地文件时也会发生同样的事情,所以我现在正在尝试解决这个问题。代码如下:

string[] files = Directory.GetFiles(@"C:\JSON_Logs");

foreach(string file in files)
{
    FileInfo fileToCompress = new FileInfo(file);
    using (FileStream originalFileStream = fileToCompress.OpenRead())
    {
        using (MemoryStream compressedMemStream = new MemoryStream())
        {
            using (GZipStream compressionStream = new GZipStream(compressedMemStream, CompressionMode.Compress))
            {
                originalFileStream.CopyTo(compressionStream);
                compressedMemStream.Seek(0, SeekOrigin.Begin);
                FileStream compressedFileStream = File.Create(fileToCompress.FullName + ".gz");

                //Eventually this will be the AWS transfer, but that's not important here
                compressedMemStream.WriteTo(compressedFileStream); 
            }
        }
    }      
}

【问题讨论】:

  • 它已经制作了一个.gz文件。 7-Zip 通常会读取 .gz 文件。我试过用文件流代替内存流,效果很好。

标签: c# filestream memorystream gzipstream


【解决方案1】:

重新排列你的using 语句,这样GZipStream 在你读取内存流内容时肯定已经完成了:

foreach(string file in files)
{
    FileInfo fileToCompress = new FileInfo(file);
    using (MemoryStream compressedMemStream = new MemoryStream())
    {
        using (FileStream originalFileStream = fileToCompress.OpenRead())
        using (GZipStream compressionStream = new GZipStream(
            compressedMemStream, 
            CompressionMode.Compress,
            leaveOpen: true))
        {
            originalFileStream.CopyTo(compressionStream);
        }
        compressedMemStream.Seek(0, SeekOrigin.Begin);

        FileStream compressedFileStream = File.Create(fileToCompress.FullName + ".gz");
        //Eventually this will be the AWS transfer, but that's not important here
        compressedMemStream.WriteTo(compressedFileStream); 
    }
}

释放流会负责刷新和关闭它。

【讨论】:

  • 没有注意到排列错误.. +1
  • 然后我在compressedMemStream.WriteTo(compressedFileStream);这一行得到一个系统异常“无法访问关闭的流”
  • @smullan:哎呀。 GZipStream 认为它拥有传递给它的流,这意味着它从我们下面关闭了 MemoryStream。无礼。我们通过传递leaveOpen 参数告诉它不要这样做。 (我们也可以通过重新排列更多代码来解决这个问题,因为 MemoryStream 在通过其数组关闭后可以读取它,但我认为这更优雅。)
猜你喜欢
  • 2019-01-30
  • 2018-03-11
  • 1970-01-01
  • 1970-01-01
  • 2017-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多