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

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

我已经看过做一个或另一个的例子,但不是两个,如果有任何“最佳实践”或任何事情,我很好奇。

对困惑感到抱歉。 我将为Web用户动态生成zip,并在HTTP响应中将其发送给他们。 不在电子邮件中。

标记

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

http://aspalliance.com/259

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

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

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

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

DotNetZip的示例ASP.NET代码

更多示例DotNetZip的ASP.NET代码

剪断:

  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 zip.AddFiles(filesToInclude, "files") zip.Save(Response.OutputStream) End Using Response.Close 

我相信其他人会推荐SharpZipLib

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

编辑

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

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

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

抓住上面的内容,当我发布这个时,我发现你的意思是通过HTTP响应返回。

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

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

摩西

我修改了一些代码如下,我使用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文件然后读取该文件的所有字节并在响应流中发送字节,最后删除临时文件和文件夹