تدفق ملف مضغوط عبر HTTP في صافي مع SharpZipLib
سؤال
وأنا جعل خدمة التحميل بسيطة جدا يمكن للمستخدم تحميل كل ما قدمه من الصور من موقع خارج. للقيام بذلك أنا فقط الرمز البريدي كل شيء للتيار HTTP.
ولكن يبدو يتم تخزين كل شيء في الذاكرة، ولم يتم إرسال البيانات سمسم ملف مضغوط اكتمال وأغلق الإخراج. أريد خدمة لبدء إرسال دفعة واحدة، وعدم استخدام الكثير من الذاكرة.
public void ProcessRequest(HttpContext context)
{
List<string> fileNames = GetFileNames();
context.Response.ContentType = "application/x-zip-compressed";
context.Response.AppendHeader("content-disposition", "attachment; filename=files.zip");
context.Response.ContentEncoding = Encoding.Default;
context.Response.Charset = "";
byte[] buffer = new byte[1024 * 8];
using (ICSharpCode.SharpZipLib.Zip.ZipOutputStream zipOutput = new ICSharpCode.SharpZipLib.Zip.ZipOutputStream(context.Response.OutputStream))
{
foreach (string fileName in fileNames)
{
ICSharpCode.SharpZipLib.Zip.ZipEntry zipEntry = new ICSharpCode.SharpZipLib.Zip.ZipEntry(fileName);
zipOutput.PutNextEntry(zipEntry);
using (var fread = System.IO.File.OpenRead(fileName))
{
ICSharpCode.SharpZipLib.Core.StreamUtils.Copy(fread, zipOutput, buffer);
}
}
zipOutput.Finish();
}
context.Response.Flush();
context.Response.End();
}
وأستطيع أن أرى ذاكرة العملية المنفذة تنمو في حين أنه يجعل الملف، ومن ثم بتحرير الذاكرة عند القيام به في الإرسال. كيف يمكنني القيام بذلك دون استخدام الكثير من الذاكرة؟
المحلول
تعطيل استجابة التخزين المؤقت مع context.Response.BufferOutput = false;
و إزالة استدعاء Flush
من نهاية التعليمات البرمجية.
نصائح أخرى
واستخدام Response.BufferOutput = كاذبة؛ في بداية ProcessRequest والاستجابة دافق بعد كل ملف.
وتحقق هذا المنصب: <وأ href = "http://www.nablasoft.com/alkampfer/index.php/2008/08/26/use-icsharpcodesharpziplib-to-write-directly-to-responseoutputstream-in-a-aspnet-application/" يختلط = "نوفولو noreferrer"> http://www.nablasoft.com/alkampfer/index.php/2008/08/26/use-icsharpcodesharpziplib-to-write-directly-to-responseoutputstream-in-a-aspnet-application /
ولمعلوماتك. هذا الرمز تعمل على إضافة متكرر شجرة كاملة من الملفات، مع يتدفقون على المتصفح:
string path = @"c:\files";
Response.Clear();
Response.ContentType = "application/zip";
Response.AddHeader("Content-Disposition", string.Format("attachment; filename=\"{0}\"", "hive.zip"));
Response.BufferOutput = false;
byte[] buffer = new byte[1024 * 1024];
using (ZipOutputStream zo = new ZipOutputStream(Response.OutputStream, 1024 * 1024)) {
zo.SetLevel(0);
DirectoryInfo di = new DirectoryInfo(path);
foreach (string file in Directory.GetFiles(di.FullName, "*.*", SearchOption.AllDirectories)) {
string folder = Path.GetDirectoryName(file);
if (folder.Length > di.FullName.Length) {
folder = folder.Substring(di.FullName.Length).Trim('\\') + @"\";
} else {
folder = string.Empty;
}
zo.PutNextEntry(new ZipEntry(folder + Path.GetFileName(file)));
using (FileStream fs = File.OpenRead(file)) {
ICSharpCode.SharpZipLib.Core.StreamUtils.Copy(fs, zo, buffer);
}
zo.Flush();
Response.Flush();
}
zo.Finish();
}
Response.Flush();