如何在 C# ASP.NET 中生成一个 .zip 文件并将其发送给用户?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/834527/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I generate and send a .zip file to a user in C# ASP.NET?
提问by MStodd
I need to construct and send a zip to a user.
我需要构建一个 zip 并将其发送给用户。
I've seen examples doing one or the other, but not both, and am curious if there are any 'best practices' or anything.
我看到过一个或另一个的例子,但不是两个,并且很好奇是否有任何“最佳实践”或任何东西。
Sorry for the confusion. I'm going to generating the zip on the fly for the web user, and sending it to them in the HTTP response. Not in an email.
对困惑感到抱歉。我将为网络用户即时生成 zip,并在 HTTP 响应中将其发送给他们。不是在电子邮件中。
Mark
标记
采纳答案by Adam Pope
I would second the vote for SharpZipLibto create the Zip file. Then you'll want to append a response header to the output to force the download dialog.
我会支持SharpZipLib创建 Zip 文件。然后,您需要将响应标头附加到输出以强制下载对话框。
should give you a good starting point to achieve that. You basically need to add a response header, set the content type and write the file to the output stream:
应该给你一个很好的起点来实现这一目标。您基本上需要添加一个响应头,设置内容类型并将文件写入输出流:
Response.AppendHeader( "content-disposition", "attachment; filename=" + name );
Response.ContentType = "application/zip";
Response.WriteFile(pathToFile);
That last line could be changed to a Response.Write(filecontents) if you don't want to save to a temp file.
如果您不想保存到临时文件,可以将最后一行更改为 Response.Write(filecontents)。
回答by Eoin Campbell
I'm sure others will recommend SharpZipLib
我相信其他人会推荐SharpZipLib
How do you intend to "send" it. .NET has built in Libraries for email via SMTP
你打算如何“发送”它。.NET 已经内置了通过 SMTP 发送电子邮件的库
EDIT
编辑
In that case you'll want to capture the output stream from SharpZipLib and write it directly to the Response. Just make sure you have the correct Mimetype set in the Response Headers (application/zip) and make sure you don't Response.Write anything else to the user.
在这种情况下,您需要从 SharpZipLib 捕获输出流并将其直接写入响应。只需确保您在响应标头(应用程序/zip)中设置了正确的 Mimetype,并确保您没有 Response.Write 任何其他内容给用户。
回答by Clinton
Agree with above, SharpZipLib, for creating .zip files in .NET, it seems a very popular option.
同意上面的SharpZipLib,用于在 .NET 中创建 .zip 文件,它似乎是一个非常流行的选择。
As for 'send'ing, if you mean via SMTP/Email, you will need to use the System.Net.Mail name space. The System.Net.Mail.AttachmentClass documentation has an example of how to send a file via email
至于“发送”,如果您的意思是通过 SMTP/电子邮件,则需要使用 System.Net.Mail 名称空间。该System.Net.Mail.Attachment类文档对如何通过电子邮件发送文件的例子
Scratch the above, by the time I posted this I see you meant return via HTTP Response.
从上面开始,当我发布此内容时,我看到您的意思是通过 HTTP 响应返回。
回答by Cheeso
DotNetZiplets you do this easily, without ever writing to a disk file on the server. You can write a zip archive directly out to the Response stream, which will cause the download dialog to pop on the browser.
DotNetZip可让您轻松完成此操作,而无需写入服务器上的磁盘文件。您可以将 zip 存档直接写入响应流,这将导致在浏览器上弹出下载对话框。
Example ASP.NET code for DotNetZip
More example ASP.NET code for DotNetZip
snip:
剪断:
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();
or in VB.NET:
或在 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
回答by ProKiner
One concern is the size of the file that you will be streaming to the client. If you use SharpZipLib to build the ZIP in-memory, you don't have any temp files to cleanup, but you'll soon run into memory issues if the files are large and a number of concurrent users are downloading files. (We experienced this pretty frequently when ZIP sizes got to the 200 MB+ range.) I worked around this by the temp file to disk, streaming it to the user, and deleting it when then request completed.
一个问题是您将流式传输到客户端的文件的大小。如果您使用 SharpZipLib 在内存中构建 ZIP,则您没有任何临时文件需要清理,但如果文件很大并且许多并发用户正在下载文件,您很快就会遇到内存问题。(当 ZIP 大小达到 200 MB+ 范围时,我们经常遇到这种情况。)我通过临时文件到磁盘,将其流式传输给用户,然后在请求完成时将其删除来解决这个问题。
回答by pashute
DotNetZip creates the stream without saving any resources on the server, so you don't have to remember to erase anything. As I said before, its fast and intuitive coding, with an efficient implementation.
DotNetZip 创建流时不会在服务器上保存任何资源,因此您不必记住删除任何内容。正如我之前所说,它快速直观的编码,具有高效的实现。
Moshe
摩西
回答by alireza
I modified some codes as below, i use System.IO.Compression
我修改了一些代码如下,我使用 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);
}
this code gets some list containing list of files copy them in temp folder , create temp zip file then read all bytes of that file and send bytes in response stream, finaly delete temp file and folder
此代码获取一些包含文件列表的列表,将它们复制到临时文件夹中,创建临时 zip 文件,然后读取该文件的所有字节并在响应流中发送字节,最后删除临时文件和文件夹