我需要构建并向用户发送zip。
我见过一个或另一个的例子,但不是两个,如果有任何“最佳实践”或其他任何内容,我很好奇。
很抱歉这个混乱。我将为Web用户动态生成zip,并在HTTP响应中将其发送给他们。不在电子邮件中。
标记
答案 0 :(得分:20)
我会选择SharpZipLib投票来创建Zip文件。然后,您需要在输出中附加响应标头以强制下载对话框。
应该为你提供一个很好的起点。您基本上需要添加响应头,设置内容类型并将文件写入输出流:
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文件然后读取该文件的所有字节并在响应流中发送字节,最后删除临时文件和文件夹