When downloading large files efficiently in ASP.NET MVC, you need to optimize memory usage, prevent timeouts, and ensure a smooth user experience. Below are the best approaches:
1. Use FileStreamResult (Efficient for Large Files)
This streams the file without loading it entirely into memory.
public ActionResult DownloadLargeFile()
{
string filePath = Server.MapPath("~/Files/LargeFile.zip"); // Adjust file path
string fileName = "LargeFile.zip";
if (!System.IO.File.Exists(filePath))
{
return HttpNotFound("File not found.");
}
var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
return File(stream, "application/octet-stream", fileName);
}
✅ Why?
- Streams the file without consuming memory.
- Works well for large files (e.g., >1GB).
2. Use Response.Write to Stream File in Chunks
This method writes file in chunks to prevent excessive memory usage.
public void StreamLargeFile()
{
string filePath = Server.MapPath("~/Files/LargeFile.zip");
if (!System.IO.File.Exists(filePath))
{
Response.StatusCode = 404;
Response.End();
return;
}
Response.Clear();
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment; filename=LargeFile.zip");
const int bufferSize = 1024 * 1024; // 1MB chunks
byte[] buffer = new byte[bufferSize];
using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
int bytesRead;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
Response.OutputStream.Write(buffer, 0, bytesRead);
Response.Flush(); // Sends the chunk immediately to the client
}
}
Response.End();
}
✅ Why?
- Sends 1MB chunks, preventing high memory usage.
- Flushes data after each chunk to avoid server timeouts.
3. Asynchronous Streaming (Recommended for Web API)
For MVC + Web API applications, use an async stream for optimal performance.
public async Task<IActionResult> DownloadLargeFileAsync()
{
string filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "Files", "LargeFile.zip");
if (!System.IO.File.Exists(filePath))
{
return NotFound("File not found.");
}
var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 4096, useAsync: true);
return File(stream, "application/octet-stream", "LargeFile.zip");
}
✅ Why?
- Asynchronous file streaming prevents thread blocking.
- useAsync: true optimizes I/O operations.
4. Enable Large File Downloads in Web.config
Modify web.config to allow large downloads:
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="2147483648" /> <!-- 2GB -->
</requestFiltering>
</security>
</system.webServer>
✅ Why?
- Increases max file size limit (default is 30MB in IIS).
5. Use Content-Disposition Header (For Better Browser Support)
If the filename contains special characters, encode it properly:
public ActionResult DownloadLargeFile()
{
string filePath = Server.MapPath("~/Files/LargeFile.zip");
string fileName = "Large File.zip";
var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
var cd = new System.Net.Mime.ContentDisposition
{
FileName = fileName,
Inline = false // Forces download
};
Response.Headers.Add("Content-Disposition", cd.ToString());
return File(stream, "application/octet-stream");
}
✅ Why?
- Prevents filename issues (especially in Chrome & Edge).
6. Optimize IIS for Large Files
If you use IIS, increase timeout settings:
- appcmd set config /section:serverRuntime /uploadReadAheadSize:10485760
- appcmd set config /section:system.webServer/serverRuntime /maxRequestEntityAllowed:2147483648
✅ Why?
- Prevents timeouts for large file downloads.
Conclusion
Hope this will help to understand file download ways and setup.