In this article, we will look at the power of the File and FileInfo classes used for file manipulation in C#. We’ll uncover the similarities and differences between these two classes and why we would want to use one over the other.
Let’s begin with some background on the File
and FileInfo
class.
The File and FileInfo Classes in C#
File
and FileInfo
are classes in C# that provide methods for manipulating files. They provide the functionalities we need to programmatically create, read, update, and delete files. Both classes are located in the System.IO
namespace and have similar functionalities. However, there are some key differences between them that we should take note of.
The File
class is a static class, which means that all of its methods are called directly on the class itself, rather than on an instance of the class. It exposes static methods which we can use to create, delete, move, or even append text to a file.
FileInfo
, on the other hand, is a non-static class, so we must create an instance of the class in order to use its methods.
The File
class has a lot of methods similar to those found in the FileInfo
class. We can use these methods interchangeably.
How to Create a File in C#
We can use the File.Create()
and FileInfo.Create()
methods to create a file:
//Create a file Using the File class using FileStream fileCreatedUsingFileClass = File.Create("myFileOne.txt"); //Create a file using the FileInfo class FileInfo fileInfo = new("myFileTwo.txt"); FileStream fileCreatedUsingFileInfoClass = fileInfo.Create();
The difference between these approaches is that File.Create()
is a static method while FileInfo.Create()
is an instance method. Also, we are required to pass in a path parameter when dealing with the File.Create()
method.
In terms of similarity, notice how File.Create()
and Fileinfo.Create()
both return a strongly typed FileStream
class. We can take it one step further by using synchronous and asynchronous methods in FileStream
to read and write files.
Let’s look at some other methods of the File
and FileInfo
classes that return a FileStream
object.
How to Open a File in C#
The File.Open()
and FileInfo.Open()
methods allow us to open a file. The Open
method has different overloads that allow us to specify the FileMode
, FileAccess
and FileStreamOptions
.
FileMode
is an enum that allows us to specify if we want to overwrite a file or create a new file if the specified one doesn’t exist:
//Open a file in Create mode using File classs using FileStream fileOne = File.Open("myFileThree.txt", FileMode.Create); //Open a file in Create mode using FileInfo FileInfo fileInfo = new("myFileTwelve.txt"); using FileStream result = fileInfo.Open(FileMode.Create);
As the name signifies, FileAccess
is an enum that allows us to specify read and write access to a file:
//Open a file with FileMode.Create, FileAccess.Write using File using FileStream fileAccess = File.Open("myFileThree.txt", FileMode.Create, FileAccess.Write); fileAccess.Close(); File.Delete("myFileThree.txt"); //Open a file with FileMode.Create, FileAccess.Write using FileInfo FileInfo fileInfo = new("myFileTwelve.txt"); using FileStream fileInfoAccess = fileInfo.Open(FileMode.Create, FileAccess.Write); fileInfoAccess.Close(); fileInfoAccess.Dispose(); fileInfo.Delete();
We can use FileShare
to specify the level of access other operations can have for a file that is in use:
//Open a file with FileMode.Create, FileAccess.Write, FileShare.ReadWrite using File using FileStream share = File.Open("myFileZ.txt", FileMode.Create, FileAccess.Write, FileShare.ReadWrite); share.Close(); share.Dispose(); //Open a file with FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite using FileInfo FileInfo fileInfo = new("myFileTwelve.txt"); using FileStream infoShare = fileInfo.Open(FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite); infoShare.Close(); infoShare.Dispose();
The last overload of the Open
method takes in a FileStreamOptions
:
var fileStreamOptions = new FileStreamOptions() { Access = FileAccess.Read, Share = FileShare.ReadWrite, Mode = FileMode.OpenOrCreate }; //Open a file with FileStreamOptions using File using FileStream fileStream = File.Open("myFileTwentyTwo.txt", fileStreamOptions); fileStream.Dispose(); File.Delete("myFileTwentyTwo.txt"); //Open a file with FileStreamOptions using FileInfo FileInfo fileInfo = new("myFileTwelve.txt"); using FileStream fileInfoFileStream = fileInfo.Open(fileStreamOptions); fileInfoFileStream.Close(); fileInfoFileStream.Dispose();
The FileStreamOptions
class allows us to specify several details used in manipulating a file – the file mode, file access, file share options, etc. We create an instance of the FileStreamOption
class and used it in opening the file using File
and FileInfo
.
How to Open a Read-only File in C#
Next, let’s look at how to open a read-only file. In this case, we will use File.OpenRead()
/ FileInfo.OpenRead()
method:
if (!File.Exists("sampleReadOnlyFileTwo.txt")) { var fs = File.Create("sampleReadOnlyFileTwo.txt"); fs.Close(); } //Open a read-only file stream with static File.OpenRead() using FileStream openReadFileResult = File.OpenRead("sampleReadOnlyFileTwo.txt"); openReadFileResult.Dispose(); File.Delete("sampleReadOnlyFileTwo.txt"); //Open a read-only file stream with instance FileInfo.OpenRead() FileInfo fileInfo = new("myFileTwo.txt"); if (!fileInfo.Exists) fileInfo.Create(); using FileStream openReadFileInfoResult = fileInfo.OpenRead(); openReadFileInfoResult.Dispose(); fileInfo.Delete();
We first create the file if it does not already exist because OpenRead
requires that the specified file exists. If we call OpenRead
on a non-existent file, an exception will be thrown.
How to Use OpenWrite Method in C#
Let’s check out how to open an existing file or create a new file for writing by using the OpenWrite()
method:
//Open or create a file stream with static File.OpenWrite() using FileStream openWriteFileResult = File.OpenWrite("myFileFive.txt"); //Open or create a file stream with instance FileInfo.OpenWrite() FileInfo fileInfo = new("myFileFourteen.txt"); using FileStream openWriteFileInfoResult = fileInfo.OpenWrite();
The OpenWrite
method always overwrites the content of a file and will create a new file for us if the file path we specified does not exist.
How to Use File With StreamReader and StreamWriter in C#
We looked at different ways in which we could create or open a file. Next, let’s check out how we can use File
with StreamWriter
and StreamReader
classes to create and read from a file.
Create a File Using CreateText
if (!File.Exists("sampleDocument.txt")) { //To create a file using (StreamWriter streamWriter = File.CreateText("sampleDocument.txt")) }
We use the CreateText
method to open and overwrite the contents of a file using StreamWriter
. If the file doesn’t exist, it will create a new file for writing UTF-8 encoded text. CreateText
returns a StreamWriter
which we can use to write to the created file.
Write to a File Using StreamWriter
We will use StreamWriter.WriteLine
to write to sampleDocument.txt
:
if (!File.Exists("sampleDocument.txt")) { //To create a file using StreamWriter streamWriter = File.CreateText("sampleDocument.txt"); //To write to the file streamWriter.WriteLine("My Todo"); streamWriter.WriteLine("Drink Water"); streamWriter.WriteLine("Be Awesome"); }
streamWriter.WriteLine
will write a string to the current stream and then add a line terminator so that the next text starts on a new line.
Read From a File Using StreamReader
We are using the StreamReader
instance to read text from a file:
using StreamReader streamReader = File.OpenText("sampleDocument.txt"); string result; StringBuilder sr = new(); while ((result = streamReader.ReadLine()) != null) { sr.Append(result); } sr.ToString();
ReadLine
is used to read the content of our file line and then we store the result in a StringBuilder
. We can simply write the result of this operation to the console by calling ToString
on the StringBuilder
:
Console.WriteLine(sr.ToString());
Let’s see how we would achieve the same result using FileInfo
.
How to Use FileInfo Class With StreamReader and StreamWriter in C#
Let’s look at how we can create a file, write to it and then read its content using FileInfo
:
FileInfo fileInfo = new("SampleDocument.txt"); if (!fileInfo.Exists) { //To create a file using StreamWriter streamWriter = fileInfo.CreateText(); //To write to the file streamWriter.WriteLine("My Todo"); streamWriter.WriteLine("Drink Water"); streamWriter.WriteLine("Be Awesome"); } //To open and read from the created .txt file using StreamReader streamReader = fileInfo.OpenText(); string result; StringBuilder sr = new(); while ((result = streamReader.ReadLine()) != null) { sr.Append(result); }
The difference here is that, unlike the File
example where we use those static classes, we use a single instance of FileInfo
to create, write and read from a file.
When to Use File Over FileInfo and Vice Versa in C#
The decision of whether to use File
or FileInfo
depends on the specific task at hand. Let’s look at key features that could influence our decision.
The Security Checks of the File Class Static Methods in C#
It is important to note that the File
class can only work on a single file at a time and that’s why we always have to specify a file path for every method call. Also, each static method of the File
class has a built-in security check designed to secure the specified file.
To put this in perspective, let’s look at our previous example where we used the File
class with a StreamWriter and StreamReader to create, write and read from a file. In that example, we made three calls – File.Exist(path)
, File.CreateText(path)
, and File.OpenText(path)
– this resulted in three security checks being performed, whether necessary or not.
On the other hand, the FileInfo
class uses a single instance and performs security checks only when necessary.
The Caching System of the FileInfo Class In C#
The FileInfo
class has a caching system, which stores the properties of a file the first time it is retrieved. This allows for faster access to file information, but it’s important to call the Refresh
method to ensure the cached information is up-to-date. If the Refresh
method is not called, we will get the outdated version of the file information:
fileInfo.Attributes = FileAttributes.Hidden; fileInfo.Refresh(); Console.WriteLine(fileInfo.Attributes.ToString());
Final Thoughts about File and FileInfo
The File
class, being a static class, is a better choice when we want to perform just a single operation on one or multiple files:
File.Copy("myFileSix.txt", "myFileSeven.txt"); File.Encrypt("myFileSix.txt"); File.Decrypt("myFileSix.txt"); File.Move("myFileSeven.txt", "myFileSix.txt"); File.Delete("myFileSix.txt"); File.Delete("myFileSeven.txt");
However, if we need to perform multiple operations on a single file and require additional functionality, then the FileInfo
class would be more suitable. It circumvents the multiple security checks of the static methods of File
class and preserves OOP:
FileInfo fileInfo = new("myFileSixteen.txt"); fileInfo.OpenText(); fileInfo.Encrypt(); fileInfo.Decrypt(); fileInfo.Delete();
Conclusion:
In this article, we have compared the File and FileInfo classes in C#. The File
and FileInfo
classes provide a powerful and flexible set of methods for file manipulation in C#. We have also looked at suggestions for when to use one over the other for better performance.