문제

사용자가 모든 이미지를 Out 사이트에서 다운로드 할 수 있도록 간단한 다운로드 서비스를 만들고 있습니다. 그렇게하기 위해 나는 모든 것을 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 코드 끝에서 전화하십시오.

다른 팁

응답을 사용합니다 .BufferOutput = false; 각 파일 후 ProcessRequest 및 플러시 응답이 시작될 때.

참고로. 이것은 브라우저로 스트리밍을 통해 전체 파일 트리를 재귀 적으로 추가하기위한 코드입니다.

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();
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top