简体   繁体   English

使用C#将文件和文件夹下载为ZIP文件在Mac中不起作用

[英]Download files and folders as a ZIP file using C# doesn't work in Mac

I'm using the following code to download a set of files and folders as a ZIP, which works great in a Windows, but not in a Mac 我正在使用以下代码以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();
                }
            }

When using a Mac, inside of the resultant ZIP the folders disappear, and the files which should be in folders are called like images\\picture1.png 使用Mac时,在生成的ZIP内,文件夹消失,应放在文件夹中的文件称为images\\picture1.png

I'm using Path.Combine to get the folder's path, could be because of that? 我正在使用Path.Combine来获取文件夹的路径,可能是因为这样吗?

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

Any advice would be great. 任何建议都很好。 :) :)

If you're using .NET Framework 4.5 or newer you can do this using the highly-efficient ASP.NET native System.IO.Compression.ZipArchive class, which should be fully compatible with any zip implementation you can find (Windows OS, MAC OS and so on). 如果您使用的是.NET Framework 4.5或更高版本,则可以使用高效的ASP.NET本机System.IO.Compression.ZipArchive类来执行此操作,该类应与您可以找到的所有zip实现完全兼容(Windows OS,MAC操作系统等)。

Here's a quick implementation sample using a MemoryStream and a couple of byte arrays representing two files: 这是一个使用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");
}

Depending on your scenario you can use it inside a MVC Controller returning an ActionResult , persist the MemoryStream to disk, replace it with a FileStream and so on: in the above example I used the Controller.File method (from System.Web.Mvc namespace) to return a FileContentResult object. 根据您的情况,您可以在返回ActionResult的MVC控制器中使用它,将MemoryStream持久化到磁盘,用FileStream替换它,依此类推:在上面的示例中,我使用了Controller.File方法(来自System.Web.Mvc命名空间) )以返回FileContentResult对象。 If you're not using the MVC Framework you cannot do that, but you can still handle the MemoryStream in a different way - by using Response.OutputStream or other standard techniques. 如果您不使用MVC框架,则无法做到这一点,但是您仍然可以以其他方式处理MemoryStream通过使用Response.OutputStream或其他标准技术。

For further info regarding this topic you can also read this post on my blog. 有关此主题的更多信息,您也可以在我的博客上阅读此帖子

I ended up using DotNetZip to create the zip file. 我最终使用DotNetZip创建了zip文件。 Here is the code I used 这是我使用的代码

    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();

No problem extracting the content from zip using a Mac. 使用Mac从zip提取内容没问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM