我使用 C# .net 4.0。我使用以下方法创建 Zip 存档:
internal void compressZip(string folderPath)
{
if (!Directory.Exists(folderPath))
{
MessageBox.Show("Directory not exist: " + folderPath);
return;
}
byte[] startBuffer = { 80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
File.WriteAllBytes(folderPath + ".zip", startBuffer);
var shellAppType = Type.GetTypeFromProgID("Shell.Application");
var oShell = Activator.CreateInstance(shellAppType);
var sourceFolder = (Shell32.Folder)shellAppType.InvokeMember("NameSpace", System.Reflection.BindingFlags.InvokeMethod, null, oShell, new object[] { folderPath });
var destinationFile = (Shell32.Folder)shellAppType.InvokeMember("NameSpace", System.Reflection.BindingFlags.InvokeMethod, null, oShell, new object[] { folderPath + ".zip" });
destinationFile.CopyHere(sourceFolder.Items(), 4 | 16);
}
但是当我尝试压缩空文件夹时出现问题。它写的是“无法将空文件夹添加到 zip 存档中”。为什么?
如果我将 CopyHere 更改为:
destinationFile.CopyHere(sourceFolder, 4 | 16);
它工作正常。但它在存档中创建父文件夹。如何使用没有父文件夹的空文件夹创建存档?
sourceFolder.Items() 包含文件夹中的所有文件和子文件夹。
sourceFolder 复制的整个文件夹,包括父文件夹。
您可以使用以下代码来压缩文件,父文件夹可以省略,空文件夹不省略:
internal void CompressZip(string folderPath)
{
if (!Directory.Exists(folderPath))
{
MessageBox.Show("Directory not exist: " + folderPath);
return;
}
string zipFilePath = folderPath + ".zip";
using (FileStream zipToCreate = new FileStream(zipFilePath, FileMode.Create))
{
using (ZipArchive archive = new ZipArchive(zipToCreate, ZipArchiveMode.Create))
{
CompressFolder(folderPath, archive, "");
}
}
}
private void CompressFolder(string folderPath, ZipArchive archive, string parentFolder)
{
foreach (var file in Directory.GetFiles(folderPath))
{
string entryName = Path.Combine(parentFolder, Path.GetFileName(file));
archive.CreateEntryFromFile(file, entryName);
}
foreach (var subFolder in Directory.GetDirectories(folderPath))
{
string entryName = Path.Combine(parentFolder, Path.GetFileName(subFolder));
var folderEntry = archive.CreateEntry(entryName + "/");
// Recursively add files and subfolders in the current subfolder
CompressFolder(subFolder, archive, entryName);
}
}
此时我的Test文件夹下有空文件夹和aaa.txt,通过上面的代码生成了Test.zip
第二次更新:
非常抱歉,我的电脑没有.net 4.0,所以测试过程中出现了一些偏差。我在寻找其他方法的过程中发现了ShareZipLip 0.86.0。它似乎不需要 .net 版本。您可以尝试以下代码:
internal void CompressZip(string folderPath)
{
if (!Directory. Exists(folderPath))
{
MessageBox. Show("Directory not exist: " + folderPath);
return;
}
string zipFilePath = folderPath + ".zip";
using (FileStream fsOut = File. Create(zipFilePath))
{
using (ZipOutputStream zipStream = new ZipOutputStream(fsOut))
{
zipStream.SetLevel(9); // Compression level, 0-9, 9 means the highest compression
CompressFolder(folderPath, zipStream, "");
}
}
}
private void CompressFolder(string folderPath, ZipOutputStream zipStream, string parentFolder)
{
string[] files = Directory. GetFiles(folderPath);
foreach (string file in files)
{
string entryName = Path. Combine(parentFolder, Path. GetFileName(file));
ZipEntry newEntry = new ZipEntry(entryName);
zipStream.PutNextEntry(newEntry);
using (FileStream fs = File. OpenRead(file))
{
byte[] buffer = new byte[4096];
StreamUtils. Copy(fs, zipStream, buffer);
}
zipStream. CloseEntry();
}
string[] subFolders = Directory. GetDirectories(folderPath);
foreach (string subFolder in subFolders)
{
string entryName = Path. Combine(parentFolder, Path. GetFileName(subFolder));
ZipEntry newEntry = new ZipEntry(entryName + "/");
zipStream.PutNextEntry(newEntry);
CompressFolder(subFolder, zipStream, entryName);
}
}