I am using C# to programatically compress an xml file. Compression works fine, but when I gunzip the file from the command line, the extension has been dropped. Why would this be?
The destination file coming in has the gz extension while the source file has an xml extension.
Here is my compression code:
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);
}
}
}
}
This also happens when I use a 3rd party library (SharpLibZip) to compress the file.
How do I keep the extension in the compressed zip file?
You should probably name your compressed files filename.xml.gz - the gz extension intentionally gets removed, and the source extension is not stored anywhere inside the archive, IIRC
I had the same problem and the other answers seem to be wrong,
Gzip has a way to store the original filename in the archive, it's specified in RFC-1952 from 1996:
If FNAME is set, an original file name is present,
terminated by a zero byte. The name must consist of ISO
8859-1 (LATIN-1) characters; [...]
Unfortunately the standard .Net System.IO.Compression library does not seem to have the ability to set the FNAME.
But you can use DotNetZip, which has almost the same interface and where GZipStream
has the additional field FileName
.
Be sure to set the FileName before the first call to Write()
, or it will fail
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);
}
}
精彩评论