몇 가지 테스트를 마친 후에 문제에 대한 다음 해결책을 찾았습니다. TransmitFile()에는 하나의 심각한 제한이 있습니다. 전송하기 전에 전체 파일을 메모리로 읽어들입니다. 이것은 대용량 파일의 경우 매우 나쁩니다. 그래서 기본적으로 클라이언트가 각 청크 다음에 연결되어 있으면 수동으로 청킹 및 확인합니다.
context.Response.Clear();
context.Response.BufferOutput = false;
context.Response.ContentType = "application/octet-stream";
context.Response.AddHeader("Content-Disposition", "attachment; filename=" + originalFilename);
context.Response.AddHeader("Content-Length", fileLength.ToString());
context.Response.Cache.SetNoStore();
context.Response.Flush();
downloadFailed = !context.Response.IsClientConnected;
int thisChunk;
long offset = 0;
int chunkSize = 1024 * 8;
byte[] bytes = new byte[chunkSize];
FileStream r = File.OpenRead(localFilename);
while((offset < fileLength) && !downloadFailed)
{
if((fileLength - offset) < chunkSize)
{
thisChunk = (int)(fileLength - offset);
}
else
{
thisChunk = chunkSize;
}
r.Read(bytes, 0, chunkSize);
try
{
context.Response.BinaryWrite(bytes);
context.Response.Flush();
if(!context.Response.IsClientConnected)
{
downloadFailed = true;
}
}
catch(ObjectDisposedException ex1)
{
// Stream is closed, nothing written
break;
}
catch(System.IO.IOException ex3)
{
// I/O error, unknown state, abort
Trace.Write(ex3);
break;
}
offset += thisChunk;
}
if(!downloadFailed)
{
// now update the file, statistics, etc
}
context.Response.Flush();
HttpContext.Current.ApplicationInstance.CompleteRequest();
최적 크기를 찾으려면 청크 크기로 비트를 재생해야합니다. 하지만 기본적으로이 기능은 안정적으로 작동합니다.
오류가 발생해도 예외가 발생하지 않습니까? –