使用C#将文件和文件夹下载为ZIP文件并不适用于Mac

时间:2014-03-21 16:55:42

标签: c# asp.net macos zip

我使用以下代码将一组文件和文件夹下载为ZIP,这在Windows中很有用,但在Mac中却不行

string SourceFolderPath = System.IO.Path.Combine(FolderPath, "Initial"); 
string SourceZip = System.IO.Path.Combine(UserTemp, nameFolder + ".zip");

            if (Directory.Exists(SourceFolderPath))
            {
                if (File.Exists(SourceZip)) { File.Delete(SourceZip); }
                ZipInfo zip = new ZipInfo(SourceZip);
                zip.Pack(SourceFolderPath, true, CompressionLevel.None, null);

                if (File.Exists(SourceZip))
                {
                    System.IO.FileInfo file = new System.IO.FileInfo(SourceZip);
                    Response.ClearContent();
                    Response.AddHeader("Content-Disposition", String.Format("attachment; filename={0}", file.Name));
                    Response.AddHeader("Content-Length", file.Length.ToString());
                    Response.ContentType = "application/zip";
                    this.EnableViewState = false;
                    Response.TransmitFile(file.FullName);
                    Response.Flush();
                    File.Delete(SourceZip);
                    Response.End();
                }
            }

使用Mac时,在生成的ZIP内部文件夹消失,应该在文件夹中的文件被称为images\picture1.png

我使用Path.Combine获取文件夹的路径,可能是因为这个原因?

string SourceFolderPath = System.IO.Path.Combine(FolderPath, "Initial"); 
string SourceZip = System.IO.Path.Combine(UserTemp, nameFolder + ".zip");

任何建议都会很棒。 :)

2 个答案:

答案 0 :(得分:2)

如果您正在使用 .NET Framework 4.5 或更新版本,则可以使用高效的ASP.NET本机System.IO.Compression.ZipArchive类来完成此操作,该类应与任何zip实现完全兼容你可以找到(Windows操作系统,MAC OS等)。

这是一个使用MemoryStream的快速实现示例和几个代表两个文件的字节数组:

byte[] file1 = GetFile1ByteArray();
byte[] file2 = GetFile2ByteArray();

using (MemoryStream ms = new MemoryStream())
{
    using (var archive = new ZipArchive(ms, ZipArchiveMode.Create, true))
    {
        var zipArchiveEntry = archive.CreateEntry("file1.txt", CompressionLevel.Fastest);
        using (var zipStream = zipArchiveEntry.Open()) zipStream.Write(file1, 0, file1.Length);
        zipArchiveEntry = archive.CreateEntry("file2.txt", CompressionLevel.Fastest);
        using (var zipStream = zipArchiveEntry.Open()) zipStream.Write(file2, 0, file2.Length);
    }
    return File(ms.ToArray(), "application/zip", "Archive.zip");
}

根据您的方案,您可以在MVC控制器中使用它,返回ActionResult,将MemoryStream保留到磁盘,将其替换为FileStream,依此类推:在上面的示例中我使用Controller.File方法(来自 System.Web.Mvc 命名空间)返回FileContentResult对象。如果您没有使用MVC框架,则无法执行此操作,但仍可以使用MemoryStream或其他标准技术以不同方式处理Response.OutputStream

有关此主题的更多信息,您还可以在我的博客上read this post

答案 1 :(得分:1)

我最终使用DotNetZip来创建zip文件。这是我使用的代码

    string SourceFolderPath = System.IO.Path.Combine(FolderPath, "Initial");

    Response.Clear();
    Response.ContentType = "application/zip";
    Response.AddHeader("Content-Disposition", String.Format("attachment; filename={0}", nameFolder + ".zip"));

    bool recurseDirectories = true;
    using (ZipFile zip = new ZipFile())
    {
        zip.AddSelectedFiles("*", SourceFolderPath, string.Empty, recurseDirectories);
        zip.Save(Response.OutputStream);
    }
    Response.End();

使用Mac从zip中提取内容没问题。