Mark
Mark

Reputation: 3271

Getting the file size of a file in C#

I want to write a file back to the client using a custom handler in ASP.Net and wondering what it the best way to do this with the least processing time. At the moment I have 2 different versions of the code that do the same thing, but because the handler will be used a lot, I'm wondering what the most efficient way is.

Load the complete file to a byte array and use BinaryWrite to write the file:

string filePath = context.Server.MapPath(context.Request.Url.LocalPath);
Byte[] swfFile = File.ReadAllBytes(filePath);
context.Response.AppendHeader("content-length", Utils.MakeString(swfFile.Length));
context.Response.ContentType = Utils.GetMimeType(Path.GetExtension(filePath));
context.Response.BinaryWrite(swfFile);

Using a FileInfo object to determine the file length and TransmitFile to write the file:

string filePath = context.Server.MapPath(context.Request.Url.LocalPath);
FileInfo fileInfo = new FileInfo(filePath);
context.Response.AppendHeader("content-length", Utils.MakeString(fileInfo.Length));
context.Response.ContentType = Utils.GetMimeType(Path.GetExtension(filePath));
context.Response.TransmitFile(filePath);

I would suspect the TransmitFile method is the most efficient because it writes without buffering the file. What about the FileInfo object? How does it calculate the file size? And is a FileInfo object the best way to do this or is there an better way?

Upvotes: 4

Views: 8212

Answers (1)

Jon
Jon

Reputation: 437376

FileInfo asks the filesystem for the file size information (it does not need to read all of the contents to do so of course). This is usually considered an "expensive" operation (in comparison to manipulating stuff in memory and calling methods) because it hits the disk.

However, while it's true that cutting down on disk accesses is a good thing, when you are preparing to read the full contents of a file anyway this won't make a difference in the grand scheme of things. So the performance of FileInfo itself is what you should be focusing on.

The #1 performance issue here is that the first approach keeps the whole file in memory for as long as the client takes to download it -- this can be a huge problem, as (depending on the size of the files and the throughput of the client connection) it has the potential of massively increasing the memory usage of your application. And if this increased memory usage leads to swapping (i.e. hitting the disk) performance will instantly tank.

So what you should do is use TransmitFile -- not because it's faster when going to the disk (it may or may not be), but because it uses less memory.

Upvotes: 5

Related Questions