Introduction
Sometimes in ASP.NET Web Forms or ASP.NET MVC applications, you put some of your secured files in a secured folder such as App_Data because you do not want users to have direct access to these files for downloading. In this situation, you write a Download.aspx file or Download.ashx http handler (in ASP.NET Web Forms), or create a download action (in ASP.NET MVC) that users can just download these files with these capabilities. There are a lot of source codes for this situation. But! If the size (length) of these files be large, for example, over 100 MB! We have two main problems.
First, we caused a very huge overhead to the server’s CPU and RAM and second, if some user tried to download a large file and after a few seconds he avoided to download the file resume, your application does not know it!
So in the below source code, I optimized the download progress, so the code get a few bytes from the file and send it to the user (client). By the way, if after a few seconds, the user (client) avoided to download the file resume, the below code recognizes it and stops sending the file resume.
Note: The below code is an action for ASP.NET MVC applications, But you can write it in Download.aspx or Download.ashx files in your ASP.NET Web Forms applications.
Using the Code
public void Download(int id)
{
string strFileName =
string.Format("{0}.zip", id);
string strRootRelativePathName =
string.Format("~/App_Data/Files/{0}", strFileName);
string strPathName =
Server.MapPath(strRootRelativePathName);
if (System.IO.File.Exists(strPathName) == false)
{
return;
}
System.IO.Stream oStream = null;
try
{
oStream =
new System.IO.FileStream
(path: strPathName,
mode: System.IO.FileMode.Open,
share: System.IO.FileShare.Read,
access: System.IO.FileAccess.Read);
Response.Buffer = false;
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment; filename=" + strFileName);
long lngFileLength = oStream.Length;
Response.AddHeader("Content-Length", lngFileLength.ToString());
long lngDataToRead = lngFileLength;
while (lngDataToRead > 0)
{
if (Response.IsClientConnected)
{
int intBufferSize = 8 * 1024;
byte[] bytBuffers =
new System.Byte[intBufferSize];
int intTheBytesThatReallyHasBeenReadFromTheStream =
oStream.Read(buffer: bytBuffers, offset: 0, count: intBufferSize);
Response.OutputStream.Write
(buffer: bytBuffers, offset: 0,
count: intTheBytesThatReallyHasBeenReadFromTheStream);
Response.Flush();
lngDataToRead =
lngDataToRead - intTheBytesThatReallyHasBeenReadFromTheStream;
}
else
{
lngDataToRead = -1;
}
}
}
catch { }
finally
{
if (oStream != null)
{
oStream.Close();
oStream.Dispose();
oStream = null;
}
Response.Close();
}
}