Writefile vs transmitefile para arquivos grandes que precisam ser excluídos do servidor após a transferência
-
25-09-2019 - |
Pergunta
Eu tenho que desencadear downloads de usuários de arquivos grandes para um webbrowser, onde crio o arquivo para transferir no servidor e excluí -lo imediatamente depois. Encontrei exemplos suficientes para ver que provavelmente deveria usar a resposta.Transmitfile ou Response.WriteFile ... mas ouvi dizer que há problemas com os dois:
O Writefile é síncrono, mas buffer o arquivo na memória antes de enviá -lo para o usuário. Como estou lidando com arquivos muito grandes, isso pode causar problemas.
O TransMitFile não buffer localmente, para que funcione para arquivos grandes, mas é assíncrono, por isso não posso excluir o arquivo depois de ligar para o transmitfile. Aparentemente, lavar o arquivo também não garante que eu possa excluí -lo?
Qual é a melhor maneira de lidar com isso?
Também há o binário ... eu poderia fazer um loop através de um fluxo de arquivos, copiando -o em segmentos?
Solução
Aqui está uma boa solução que usa transmissão, mas permite que você faça algo assim que for feito usando um delegado:
http://improve.dk/blog/2008/03/29/response-transmitfile-close-will-kill-your-aplication
Basta substituir o log no final pela exclusão do arquivo.
Outras dicas
O Writefile é síncrono, mas buffer o arquivo na memória antes de enviá -lo para o usuário. Como estou lidando com arquivos muito grandes, isso pode causar problemas.
Eu acredito que você pode desativar o buffer para escrever arquivo definindo a resposta.bufferOutput = false;
Uma vez que isso tenha sido definido como false, você poderá chamar o writefile sem buffer ...
Você poderia comprometer o arquivo no disco (nome aleatório etc.) e começar a enviar, mas adicione uma entrada a uma tabela de banco de dados com o nome do arquivo temporário, após um período de tempo que você define, faça algum trabalho de limpeza passar por essas entradas de banco de dados e excluir e excluir o arquivo do disco se tiver envelhecido.
Writefile O método é usado para baixar o arquivo pequeno do servidor, o parâmetro de tamanho deve estar entre zero e o valor máximo INT32, antes de transferir o arquivo que buffer no arquivo na memória. Transmitefile O método é usado para baixar o arquivo grande do servidor e não buffer o arquivo na memória. Mas, ao tentar excluir o arquivo enquanto o baixar, ele lança a exceção. Abaixo está o código que excluiria o arquivo após o download.
FileStream fs = new FileStream(@"D:\FileDownLoad\DeskTop.zip", FileMode.OpenOrCreate);
MemoryStream ms = new MemoryStream();
fs.CopyTo(ms);
context.Response.AppendHeader("content-disposition", "attachment; filename=" + "DeskTop.zip");
context.Response.ContentType = "application/octet-stream";
context.Response.BinaryWrite(ms.ToArray());
fs.Close();
File.Delete(@"D:\FileDownLoad\DeskTop.zip");