@ErocM @Flydog57 提供的链接为您提供了您想要的。您没有正确利用entryName 参数(调用CreateEntryFromFile 时的第二个参数)。
独立于要添加到存档的文件(来自不同文件夹的相同文件),您必须使用 C# api 提供给您的 entryName 参数来构建存档。
如果您的文件全名是/tmp/myfile.txt,而您使用的是archive.CreateEntryFromFile(item.FullName, item.Name),那么存档条目名称将为myfile.txt。没有作为条目名称创建的文件夹在其名称中不包含文件夹结构。
但是,如果您调用archive.CreateEntryFromFile(item.FullName, item.FullName),您将在存档中拥有您的文件夹结构。
您可以尝试使用您的函数,只需将 item.Name 更改为 item.FullName。
在 Windows 上要小心;例如,如果您的路径是 C:\tmp\myfile.txt,则存档将无法正确提取。然后,您可以添加一些小代码以从文件的全名中删除 C:。
一些实施示例:
using System;
using System.IO;
using System.Collections.Generic;
using System.IO.Compression;
namespace ConsoleApp
{
internal class Program
{
static void Main(string[] args)
{
FileInfo f1 = new FileInfo(@"/tmp/test1.txt");
FileInfo f2 = new FileInfo(@"/tmp/testdir/test2.txt");
List<FileInfo> files = new();
files.Add(f1);
files.Add(f2);
CreateZipFile(files, @"/tmp/archive.zip");
}
public static void CreateZipFile(IEnumerable<FileInfo> files, string archiveName)
{
using (var stream = File.OpenWrite(archiveName))
using (var archive = new ZipArchive(stream, ZipArchiveMode.Create))
{
foreach (var item in files)
{
// Here for instance, I put all files in the input list in the same directory, without checking from where they are in the host file system.
archive.CreateEntryFromFile(item.FullName, $"mydir/{item.Name}", CompressionLevel.Optimal);
// Here, I am just using the actual full path of the file. Be careful on windows with the disk name prefix (C:, D:, etc...).
// archive.CreateEntryFromFile(item.FullName, item.FullName, CompressionLevel.Optimal);
}
}
}
}