SharpZipLib:将单个文件压缩为单个压缩文件

6

我目前正在使用.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);

这个功能基本上(有点)像它应该的一样工作,但是在测试时我遇到了一个小问题。假设我的临时目录(即包含未压缩输入文件的目录)包含以下文件:

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文件都包含在压缩归档文件中。这是因为传递给CreateZip方法的最终fileFilter参数。在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();
        }
    }
}

2
关于你的旁白:ZipStream 没有太多意义,因为 ZIP 是一种可以容纳多个文件的存档格式。我想他们本来可以提供一个完整的 API 来读写 ZIP 文件,但这显然需要比 GZipStream 更多的工作量。 - Marcelo Cantos
作为我的一小建议,因为您只压缩一个文件,是否有任何原因您不想使用 GZip 压缩?如您所述,该压缩方式在框架内得到支持。 - Rowland Shaw
我很乐意这样做,只需要几行代码就可以了。必须使用zip格式,因为我们的“支持”桌面无法处理gzip的复杂性(这听起来有点讽刺吗?;))。 - MrEyes
1个回答

5

那个可以用,但是压缩的归档文件也包括了所有的目录。如果归档文件只包含根目录下的文件而没有其他内容会更好。 - MrEyes
1
string entryName = System.IO.Path.GetFileName(filename);将文件名转换为入口名称。 - Hans Passant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接