Pergunta

Eu estou fazendo um serviço de download simples para que um usuário pode baixar todas as suas imagens do local para fora. Para fazer isso eu apenas zip tudo para o fluxo de http.

No entanto, parece tudo é armazenado na memória e os dados não são enviados até zip arquivo está completo ea saída fechada. Eu quero o serviço para iniciar o envio de uma vez, e não usar muita memória.

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();
}

Eu posso ver a memória do processo de trabalho em crescimento, enquanto ele faz o arquivo e, em seguida, libera a memória quando o seu feito enviando. Como posso fazer isso sem usar muita memória?

Foi útil?

Solução

Disable buffer de resposta com context.Response.BufferOutput = false; e remover a chamada Flush partir do final do seu código.

Outras dicas

uso Response.BufferOutput = false; no início do ProcessRequest ea resposta nivelada depois de cada arquivo.

FYI. Este código está trabalhando para adicionar recursivamente uma árvore inteira de arquivos, com streaming para navegador:

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();
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top