Beware of the FileInfo.OpenText() method

Jul 17, 2007

I’m a big fan of the System.IO.FileInfo object in .NET because it wraps the System.IO.File object nicely in a strongly typed way. It makes it easier to work with files. The FileInfo class has a method called OpenText that returns a StreamReader instance which can then be read into a string and other things.

If you use the OpenText method read the text of a file, then the easiest way is like so:

FileInfo fi = new FileInfo("C:\\currency.xml");
string content = fi.OpenText().ReadToEnd();

Now the content variable contains the text content of the currency.xml file, but there is a problem with this approach. Because the OpenText method creates a StreamReader instance which we then call the ReadToEnd method on, the StreamReader keeps a lock on the file. The can cause many problems and must be avoided.

Instead you could do like so, which releases the file handle when the StreamReader is disposed:

FileInfo fi = new FileInfo("C:\\currency.xml");
StreamReader reader = fi.OpenText();
string content = reader.ReadToEnd();
reader.Dispose();

This works fine, but we doubled the lines needed to read the text. This might not be an issue, but then we could just as well just use the StreamReader directly without using the FileInfo class like so:

using (StreamReader reader = new StreamReader("C:\\currency.xml"))
{
  string content = reader.ReadToEnd(); 
}

It is much cleaner than using the FileInfo class and the intent is very clear as well.

* Only $4.95/month ASP.NET & Windows 2008 + IIS 7 Hosting! FREE SQL Included

Comments (6) -

Josh Stodola
Josh Stodola United States
7/17/2007 8:21:13 PM #

I have always used the stream reader directly and instantiated it by passing it the file path, like so:

[code lang="vb"]
Dim Reader as New StreamReader("C:\currency.xml")
Dim Content as String = Reader.ReadToEnd()
Reader.Close()
[/code]

Marc
Marc United Kingdom
7/18/2007 7:16:08 AM #

Hi,

Can't you just use:
<code>
using System.IO;

string s = File.ReadAllText("C:\currency.xml")
</code>

This opens and closes the file for you.

Mads Kristensen
Mads Kristensen Denmark
7/18/2007 7:51:56 AM #

Marc, yes that also works great. The idea is, that you shouldn't blindly use the FileInfo's OpenText() method.

Michael Sivers
Michael Sivers United Kingdom
7/18/2007 9:29:25 AM #

Is this why the theme CSS file in BlogEngine.NET 1.0 would get locked when editing live after viewing the site. I assume it has subsequently been fixed? I haven't upgraded yet though!

Mads Kristensen
Mads Kristensen Denmark
7/18/2007 9:52:44 AM #

Michael, that was exactly what happened. I thought I should warn others of the approach. It has been fixed a long time ago in BlogEngine

Bill Williamson
Bill Williamson Australia
7/19/2007 2:16:28 AM #

This is true of resources gained by ANY method call.  It is what differentiates a Property (which CAN run code) from a method.

If it was a property "FileInfo.TextReader" then you could assume it's safe, and will always return an equivilant one.  The fact that it's a method call should alert anyone that you shouldn't call it inline.

We run into this TONS in the SharePoint world, where people try to use a "SPSite.OpenWeb()" call again and again, unaware that it's opening a new connection each and every time!

Comments are closed

About the author

Mads Kristensen

Mads Kristensen
Program Manager at the Microsoft Web Platform team and founder of BlogEngine.NET.

More...

Month List

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer’s view in any way.