ASP.NET Response.WriteFile

File: text page

Response.WriteFile handles binary data from a file. With WriteFile, we write a binary file (such as a PNG) to the Response buffer. It affects performance because the disk is accessed. This method is useful but has its drawbacks.

Example

First, we see that the Response.WriteFile method directly inserts the bytes of another file into your ASPX page. This code inserts a PNG image into the ASPX file. The image is displayed as a graphic in the browser.

Class that calls Response.WriteFile: C#

using System;
using System.Web;
using System.Web.UI;
using System.IO;
using System.Diagnostics;

public partial class C_Default : Page
{
    protected override void OnLoad(EventArgs e)
    {
	//
	// Here we always give visitors the image.
	//
	WriteData();
	base.OnLoad(e);
    }

    private void WriteData()
    {
	Response.ContentType = "image/png";
	Response.WriteFile("Logo-Pale-Fireworks.png", true);
    }
}
Note

The above code always is run when the user loads the Default.aspx page. There is a file called "Logo-Pale-Fireworks.png" that is in the same directory. It shows users the PNG image.

Note:When the user's browser accesses Default.aspx above, it shows the Logo-Pale-Fireworks.png image.

Performance optimization

In my testing, that approach is many times slower that using a custom byte[] cache. For some reason, the file system cache is easily defeated. This problem would likely still be present on the deployment installation.

Example 2

Byte type

We can just put the image's bytes into an array and store it in a static class. I felt the overhead of the C# code might outweigh the benefits here, but I was wrong. Using the byte[] cache here can ensure that the cache will be hit.

Byte Array: Memory Usage, Read All Bytes
Class that writes byte array: C#

using System;
using System.Web;
using System.Web.UI;
using System.IO;
using System.Diagnostics;

public partial class C_Default : Page
{
    protected override void OnLoad(EventArgs e)
    {
	//
	// Always give visitors the image
	//
	WriteData();
	base.OnLoad(e);
    }

    private void WriteData()
    {
	Response.ContentType = "image/png";
	Response.BinaryWrite(SiteData.Logo);
    }
}

In the above code block, you will see the line Response.BinaryWrite(SiteData.Logo). This is accessing the static property containing the bytes of the logo named "Logo-Pale-Fireworks.png".

Response.BinaryWrite

Example 3

Here, I put the above code in a new file in the App_Code folder. It uses a static constructor, which means it will only run once. A static constructor is usually run in a lazy way. The code is more complicated.

Class that stores byte cache: C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;

public static class SiteData
{
    public static byte[] Logo
    {
	get
	{
	    return _logoBytes;
	}
    }

    static byte[] _logoBytes;

    static SiteData()
    {
	//
	// Caching the file this way is much faster than using WriteFile.
	//
	_logoBytes = File.ReadAllBytes(HttpContext.Current.Server.MapPath(
	    "~/C/Logo-Pale-Fireworks.png"));

    }
}

Discussion

Static

The static class is faster for repeated usages. Often on the server, the first approach (WriteFile) will be slower because the file may not be in the file system cache. The second approach guarantees the file will be in memory.

Static Class

Performance. There is an obvious performance improvement by manually caching bytes. The above code blocks were executed 1000 times each, with the response buffer being cleared with Response.Clear() each iteration.

Benchmark results

Response.WriteFile usage:           10.680 s
Byte[] cache, Response.BinaryWrite:  0.094 s

Summary

The C# programming language

We saw the Response.WriteFile method in ASP.NET using the C# language. We should not rely on file system caches for optimal performance. We use Cache objects or static classes to ensure a static resource is resident in memory.

Note:My experience is that custom C# code is often better for performance than using ASP.NET methods such as Response.WriteFile.


C#: ASP.NET