如何在C#ASP.NET中生成.zip文件并将其发送给用户?

如何在C#ASP.NET中生成.zip文件并将其发送给用户?,c#,asp.net,file,zip,C#,Asp.net,File,Zip,我需要构造一个zip并发送给用户 我见过这样或那样的例子,但不是两者都有,我很好奇是否有“最佳实践”或其他什么 很抱歉给你带来了困惑。我将为web用户动态生成zip,并在HTTP响应中将其发送给他们。不是在电子邮件中 马克我相信其他人会推荐 你打算如何“发送”它。NET内置了用于通过SMTP发送电子邮件的库 编辑 在这种情况下,您需要从SharpZipLib捕获输出流,并将其直接写入响应。只需确保在响应头(应用程序/zip)中设置了正确的Mimetype,并确保没有响应。向用户写入任何其他内容。

我需要构造一个zip并发送给用户

我见过这样或那样的例子,但不是两者都有,我很好奇是否有“最佳实践”或其他什么

很抱歉给你带来了困惑。我将为web用户动态生成zip,并在HTTP响应中将其发送给他们。不是在电子邮件中


马克

我相信其他人会推荐

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

编辑


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

我会支持创建zip文件。然后,您需要将响应头附加到输出,以强制下载对话框

应该给你一个很好的起点来实现这一点。您基本上需要添加响应头、设置内容类型并将文件写入输出流:

Response.AppendHeader( "content-disposition", "attachment; filename=" + name );
Response.ContentType = "application/zip";
Response.WriteFile(pathToFile);
如果您不想保存到临时文件,最后一行可以更改为Response.Write(filecontents)。

同意上面的说法,对于在.NET中创建.zip文件,这似乎是一个非常流行的选项

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

请注意上面的内容,当我发布这篇文章时,我发现您的意思是通过HTTP响应返回。

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

剪报:

或在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
响应。清除
Response.BufferOutput=false
将ReadmeText设置为String=“README.TXT\n\nHello!\n\n”&_
“这是在ASP.NET中生成的zip文件”
Dim archiveName as String=String.Format(“archive-{0}.zip”_
DateTime.Now.ToString(“yyyy-MMM-dd-HHmmss”))
Response.ContentType=“应用程序/zip”
Response.AddHeader(“内容处置”、“文件名=“+archiveName”)
将zip用作新的ZipFile()
AddEntry(“Readme.txt”,“ReadmeText”,Encoding.Default)
“”filesToInclude是字符串[]或列表
zip.AddFiles(filesToInclude,“files”)
zip.Save(Response.OutputStream)
终端使用
回应,结束

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

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


Moshe

我修改了一些代码,如下所示,我使用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);
    }  
publicstaticvoidzip(HttpResponse响应,HttpServerUtility服务器,字符串[]路径)
{
Response.Clear();
Response.BufferOutput=false;
string archiveName=string.Format(“archive-{0}.zip”,
DateTime.Now.ToString(“yyyy-MMM-dd-hhmms”);
Response.ContentType=“应用程序/zip”;
Response.AddHeader(“内容处置”、“文件名=“+archiveName”);
var path=Server.MapPath(@../TempFile/TempFile“+DateTime.Now.Ticks);
如果(!Directory.Exists(Server.MapPath(@./TempFile)))
CreateDirectory(Server.MapPath(@./TempFile));
如果(!Directory.Exists(path))
CreateDirectory(路径);
var-pathzipfile=Server.MapPath(@../TempFile/zip_“+DateTime.Now.Ticks+.zip”);
for(int i=0;i
此代码获取一些包含文件列表的列表,并将它们复制到临时文件夹中
,创建临时zip文件,然后读取该文件的所有字节并在响应流中发送字节,最后删除临时文件和文件夹

截至2014年9月(和.Net 4.5)为止,C#的最佳zip库DotNetZip现在不可靠,经常生成损坏或无法打开的zip存档。真遗憾,因为在我拥有它的第一年左右,它工作得很好。
 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);
    }