ASP.NET has a problem with file downloads...basically if you use Response.WriteFile(fileName), the entire file is buffered in memory before its' downloaded - this is NOT good for scalability. To get round that proble, here's some code which could be used for file download - it looks the file download, only downloading chunks at a time. Also checks that the client is connected before sending the next chunk...
private void DownloadFile(Guid itemId)
{
//Where to start in the file
long startPos = 0;
//How big a chunk to download in each iteration
long chunkSize = 20480;
//Use the id to retreive the resource files details
using(SqlDataReader reader=SqlExtra.ExecuteReader("GetResource", itemId))
{
try
{
if(reader.Read())
{
//Get the file details we need to save a copy to the client
string fileExtension=reader["FileTypeExtension"].ToString();
string fileNameClient=reader["FileName"].ToString();
string fileNameServer=Server.MapPath(string.Format(@"Uploads/{0}{1}", itemId.ToString(), fileExtension));
FileInfo file=new FileInfo(fileNameServer);
//Only proceed with the download if the file physically exists
if (file.Exists)
{
//Setup the Response object to allow file downloads
Response.Clear();
Response.ContentType = "application/octet-stream";
//Attach the file to the response stream.
Response.AddHeader("Content-Disposition", string.Format("{0}{1}", "attachment; filename=", fileNameClient));
Response.AddHeader("Content-Length",file.Length.ToString());
long fileSize = file.Length;
try
{
while(startPos < file.Length)
{
if(Response.IsClientConnected)
{
//write the file to the client
if(startPos + chunkSize > fileSize)
{
chunkSize = fileSize - startPos;
}
Response.WriteFile(fileNameServer,startPos,chunkSize);
Response.Flush();
startPos += chunkSize;
}
else
{
break;
}
}
}
catch(Exception ex)
{
ExceptionManager.Publish(ex);
}
Response.End();
}
else
{
//display an error message
StatusMessage.Text=fileNameClient;
}
}
}
catch(Exception ex)
{
if(ex.GetType() != typeof(System.Threading.ThreadAbortException))
{
ExceptionManager.Publish(ex);
}
}
}
}
Hope you find it useful... sorry about the formatting...seems this page isn't very flexible...hmm...
© 2025 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.