为什么我的程序化压缩会丢弃文件扩展名?

时间:2010-06-19 16:22:48

标签: c# compression gzip gzipstream gunzip

我正在使用C#以编程方式压缩xml文件。压缩工作正常,但是当我从命令行压缩文件时,扩展名已被删除。为什么会这样?

进入的目标文件具有gz扩展名,而源文件具有xml扩展名。

这是我的压缩代码:

            using (FileStream input = File.OpenRead(filename))
            {
                using (var raw = File.Create(destFilename))
                {
                    using (Stream gzipStream = new GZipStream(raw, CompressionMode.Compress))
                    {
                        byte[] buffer = new byte[4096];
                        int n;
                        while ((n = input.Read(buffer, 0, buffer.Length)) != 0)
                        {
                            gzipStream.Write(buffer, 0, n);
                        }
                    }
                }
            }

当我使用第三方库(SharpLibZip)压缩文件时,也会发生这种情况。

如何将扩展名保留在压缩的zip文件中?

2 个答案:

答案 0 :(得分:4)

您应该将您的压缩文件命名为filename.xml.gz - 有意删除gz扩展名,并且源扩展名不会存储在存档内的任何位置,IIRC

答案 1 :(得分:1)

我遇到了同样的问题,其他答案似乎是错误的,

Gzip提供了一种将原始文件名存储在存档中的方法,它是从1996年的RFC-1952中指定的:

  

如果设置了FNAME,则存在原始文件名,
  以零字节终止。名称必须包含ISO
  8859-1(LATIN-1)个字符; [...]

不幸的是,标准.Net System.IO.Compression库似乎无法设置FNAME。
但是您可以使用DotNetZip,它具有几乎相同的界面,并且GZipStream具有附加字段FileName
请确保在第一次调用Write()之前设置FileName,否则它将失败

public void GzipFileNoOverwrite(string src, string dst)
{
    var bytes = File.ReadAllBytes(src);
    using (FileStream fs =new FileStream(dst, FileMode.CreateNew))
    using (GZipStream zipStream = new GZipStream(fs, CompressionMode.Compress, CompressionLevel.Level8, false))
    {
        zipStream.FileName = Path.GetFileName(src) ?? throw new ArgumentException($"Can't get filename from '{src}'");
        zipStream.Write(bytes, 0, bytes.Length);
    }
}