如何在C#ASP.NET中为用户生成和发送.zip文件?

时间:2009-05-07 13:02:08

标签: c# asp.net file zip

我需要构建并向用户发送zip。

我见过一个或另一个的例子,但不是两个,如果有任何“最佳实践”或其他任何内容,我很好奇。

很抱歉这个混乱。我将为Web用户动态生成zip,并在HTTP响应中将其发送给他们。不在电子邮件中。

标记

7 个答案:

答案 0 :(得分:20)

我会选择SharpZipLib投票来创建Zip文件。然后,您需要在输出中附加响应标头以强制下载对话框。

http://aspalliance.com/259

应该为你提供一个很好的起点。您基本上需要添加响应头,设置内容类型并将文件写入输出流:

Response.AppendHeader( "content-disposition", "attachment; filename=" + name );
Response.ContentType = "application/zip";
Response.WriteFile(pathToFile);

如果您不想保存到临时文件,那么最后一行可以更改为Response.Write(filecontents)。

答案 1 :(得分:10)

DotNetZip可让您轻松完成此操作,而无需写入服务器上的磁盘文件。您可以直接将zip存档写入Response流,这将导致下载对话框在浏览器上弹出。

Example ASP.NET code for DotNetZip

More example ASP.NET code for DotNetZip

剪断:

    Response.Clear();
    Response.BufferOutput = false; // false = stream immediately
    System.Web.HttpContext c= System.Web.HttpContext.Current;
    String ReadmeText= String.Format("README.TXT\n\nHello!\n\n" + 
                                     "This is text for a readme.");
    string archiveName= String.Format("archive-{0}.zip", 
                                      DateTime.Now.ToString("yyyy-MMM-dd-HHmmss")); 
    Response.ContentType = "application/zip";
    Response.AddHeader("content-disposition", "filename=" + archiveName);

    using (ZipFile zip = new ZipFile())
    {
        zip.AddFiles(f, "files");            
        zip.AddFileFromString("Readme.txt", "", ReadmeText);
        zip.Save(Response.OutputStream);
    }
    Response.Close();

或在VB.NET中:

    Response.Clear
    Response.BufferOutput= false
    Dim ReadmeText As String= "README.TXT\n\nHello!\n\n" & _
                              "This is a zip file that was generated in ASP.NET"
    Dim archiveName as String= String.Format("archive-{0}.zip", _
               DateTime.Now.ToString("yyyy-MMM-dd-HHmmss"))
    Response.ContentType = "application/zip"
    Response.AddHeader("content-disposition", "filename=" + archiveName)

    Using zip as new ZipFile()
        zip.AddEntry("Readme.txt", "", ReadmeText, Encoding.Default)
        '' filesToInclude is a string[] or List<String>
        zip.AddFiles(filesToInclude, "files")            
        zip.Save(Response.OutputStream)
    End Using
    Response.Close

答案 2 :(得分:2)

我相信其他人会推荐SharpZipLib

你打算如何“发送”它。 .NET内置了通过SMTP发送电子邮件的库

修改

在这种情况下,您需要捕获SharpZipLib的输出流并将其直接写入Response。只需确保在响应标题(应用程序/ zip)中设置了正确的Mimetype,并确保没有Response.Write给用户任何其他内容。

答案 3 :(得分:0)

同意上面的SharpZipLib,在.NET中创建.zip文件,它似乎是一个非常受欢迎的选项。

对于“发送”,如果您的意思是通过SMTP /电子邮件,则需要使用System.Net.Mail名称空间。 System.Net.Mail.Attachment类文档有一个如何通过电子邮件发送文件的示例

如上所述,当我发布此消息时,我发现您的意思是通过HTTP响应返回。

答案 4 :(得分:0)

一个问题是您要传输到客户端的文件大小。如果您使用SharpZipLib在内存中构建ZIP,则没有任何临时文件可以清理,但如果文件很大并且许多并发用户正在下载文件,您很快就会遇到内存问题。 (当ZIP大小达到200 MB +范围时,我们经常遇到这种情况。)我通过临时文件解决了这个问题,将其传输给用户,然后在请求完成时将其删除。

答案 5 :(得分:0)

DotNetZip创建流而不保存服务器上的任何资源,因此您不必记住删除任何内容。正如我之前所说,它快速直观的编码,具有高效的实现。

摩西

答案 6 :(得分:0)

我修改了一些代码,如下所示,我使用System.IO.Compression

 public static void Zip(HttpResponse Response, HttpServerUtility Server, string[] pathes)
    {
        Response.Clear();
        Response.BufferOutput = false;         

        string archiveName = String.Format("archive-{0}.zip",
                                          DateTime.Now.ToString("yyyy-MMM-dd-HHmmss"));
        Response.ContentType = "application/zip";
        Response.AddHeader("content-disposition", "filename=" + archiveName);

        var path = Server.MapPath(@"../TempFile/TempFile" + DateTime.Now.Ticks);
        if (!Directory.Exists(Server.MapPath(@"../TempFile")))
            Directory.CreateDirectory(Server.MapPath(@"../TempFile"));

        if (!Directory.Exists(path))
            Directory.CreateDirectory(path);
        var pathzipfile = Server.MapPath(@"../TempFile/zip_" + DateTime.Now.Ticks + ".zip");
        for (int i = 0; i < pathes.Length; i++)
        {
            string dst = Path.Combine(path, Path.GetFileName(pathes[i]));
            File.Copy(pathes[i], dst);
        }
        if (File.Exists(pathzipfile))
            File.Delete(pathzipfile);
        ZipFile.CreateFromDirectory(path, pathzipfile);
        {
            byte[] bytes = File.ReadAllBytes(pathzipfile);
            Response.OutputStream.Write(bytes, 0, bytes.Length);
        }
        Response.Close();
        File.Delete(pathzipfile);
        Directory.Delete(path, true);
    }  

此代码获取一些包含文件列表的列表,将它们复制到临时文件夹中 ,创建临时zip文件然后读取该文件的所有字节并在响应流中发送字节,最后删除临时文件和文件夹