我目前正在使用.NET 2.0下的SharpZipLib,因此我需要将单个文件压缩为单个压缩存档。为了做到这一点,我目前正在使用以下内容:
string tempFilePath = @"C:\Users\Username\AppData\Local\Temp\tmp9AE0.tmp.xml";
string archiveFilePath = @"C:\Archive\Archive_[UTC TIMESTAMP].zip";
FileInfo inFileInfo = new FileInfo(tempFilePath);
ICSharpCode.SharpZipLib.Zip.FastZip fZip = new ICSharpCode.SharpZipLib.Zip.FastZip();
fZip.CreateZip(archiveFilePath, inFileInfo.Directory.FullName, false, inFileInfo.Name);
这应该是正确的(ish),但是在测试时我遇到了一个小问题。可以说我的临时目录(即包含未压缩输入文件的目录)包含以下文件:
tmp9AE0.tmp.xml //The input file I want to compress
xxx_tmp9AE0.tmp.xml // Some other file
yyy_tmp9AE0.tmp.xml // Some other file
wibble.dat // Some other file
当我运行压缩时,所有.xml
文件都包含在压缩存档中。这是因为传递给fileFilter
方法的最终CreateZip
参数。在引擎盖下,SharpZipLib正在执行模式匹配,这也会选取前缀为xxx_
和yyy_
的文件。我认为它也可以拾取任何后缀。
所以问题是,如何使用SharpZipLib压缩单个文件?然后,问题可能是我如何格式化fileFilter
,以便匹配只能获取我想要压缩的文件,而不是其他任何内容。
顺便说一下,为什么System.IO.Compression
不包含ZipStream
类,有什么理由吗? (它只支持GZipStream)
编辑:解决方案(源自Hans Passant的接受答案)
这是我实施的压缩方法:
private static void CompressFile(string inputPath, string outputPath)
{
FileInfo outFileInfo = new FileInfo(outputPath);
FileInfo inFileInfo = new FileInfo(inputPath);
// Create the output directory if it does not exist
if (!Directory.Exists(outFileInfo.Directory.FullName))
{
Directory.CreateDirectory(outFileInfo.Directory.FullName);
}
// Compress
using (FileStream fsOut = File.Create(outputPath))
{
using (ICSharpCode.SharpZipLib.Zip.ZipOutputStream zipStream = new ICSharpCode.SharpZipLib.Zip.ZipOutputStream(fsOut))
{
zipStream.SetLevel(3);
ICSharpCode.SharpZipLib.Zip.ZipEntry newEntry = new ICSharpCode.SharpZipLib.Zip.ZipEntry(inFileInfo.Name);
newEntry.DateTime = DateTime.UtcNow;
zipStream.PutNextEntry(newEntry);
byte[] buffer = new byte[4096];
using (FileStream streamReader = File.OpenRead(inputPath))
{
ICSharpCode.SharpZipLib.Core.StreamUtils.Copy(streamReader, zipStream, buffer);
}
zipStream.CloseEntry();
zipStream.IsStreamOwner = true;
zipStream.Close();
}
}
}