C# IOException
last modified October 16, 2026
In this article we show how to handle I/O errors in C#.
Working with files, directories, and network connections often causes errors: a
file does not exist, a disk is full, or a connection is lost. .NET reports these
errors with exceptions. The base class of I/O exceptions is
IOException from the System.IO namespace.
The following more specific exceptions derive from IOException:
FileNotFoundExceptionDirectoryNotFoundExceptionDriveNotFoundExceptionPathTooLongExceptionEndOfStreamExceptionFileLoadException
The exceptions are handled with the try/catch statement. Users of
our programs should be presented with easy to understand error messages. More
technical details are reserved for administrators; they are often written to log
files.
C# unhandled exception
The documentation of each I/O method lists the exceptions that it may throw. For
instance, the File.ReadAllText method opens a text file, reads all
the text in the file, and then closes the file. It throws a
FileNotFoundException if the file does not exist.
var filename = "words.txt"; var content = File.ReadAllText(filename); Console.WriteLine(content);
The example reads the contents of a text file. There is no exception handling in the program.
$ dotnet run Unhandled exception. System.IO.FileNotFoundException: Could not find file '/home/user/app/words.txt'. ...
Since the file is missing, the runtime terminates the program and prints the exception with its stack trace.
C# catching IOException
In the next example, we handle the possible error with
try/catch.
var filename = "words.txt";
try
{
var content = File.ReadAllText(filename);
Console.WriteLine(content);
}
catch (FileNotFoundException e)
{
Console.WriteLine("Failed to read the file");
Console.WriteLine($"The file {Path.GetFileName(e.FileName)} does not exist");
}
One of the goals of exception handling is to provide understandable error messages to the users.
Console.WriteLine($"The file {Path.GetFileName(e.FileName)} does not exist");
The FileName property of the exception contains the full path of
the missing file.
$ dotnet run Failed to read the file The file words.txt does not exist
C# order of catch blocks
A catch block for a base exception also catches the derived
exceptions. Therefore, more specific exceptions must be caught first; if a
catch (IOException) block preceded a
catch (FileNotFoundException) block, the compiler would report the
CS0160 error.
string[] paths = ["words.txt", "data/words.txt", "/etc/shadow"];
foreach (var path in paths)
{
try
{
Console.WriteLine(File.ReadAllText(path));
}
catch (FileNotFoundException)
{
Console.WriteLine($"file not found: {path}");
}
catch (DirectoryNotFoundException)
{
Console.WriteLine($"directory not found: {path}");
}
catch (IOException e)
{
Console.WriteLine($"I/O error: {e.Message}");
}
catch (UnauthorizedAccessException)
{
Console.WriteLine($"access denied: {path}");
}
}
We try to read three files. The first one does not exist, the second one is in a directory that does not exist, and the third one is a Linux system file that ordinary users cannot read.
catch (UnauthorizedAccessException)
Note that UnauthorizedAccessException does not derive from
IOException; the catch (IOException) block does not
catch it. It is a common source of unhandled exceptions in file-processing
code.
$ dotnet run file not found: words.txt directory not found: data/words.txt access denied: /etc/shadow
C# file in use
A plain IOException is thrown, for instance, when a file is locked
by another stream or another process.
var path = "log.txt";
using var first = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None);
try
{
using var second = new FileStream(path, FileMode.Open, FileAccess.Read);
}
catch (IOException e)
{
Console.WriteLine(e.GetType().Name);
Console.WriteLine(e.Message);
}
The first stream opens the file with FileShare.None; no other
stream may open the file until the first one is closed.
$ dotnet run IOException The process cannot access the file '/home/user/app/log.txt' because it is being used by another process.
C# exception hierarchy
We can check the base class of an exception type with the
BaseType property.
Type[] types = [typeof(FileNotFoundException), typeof(EndOfStreamException),
typeof(PathTooLongException), typeof(UnauthorizedAccessException),
typeof(OperationCanceledException)];
foreach (var type in types)
{
Console.WriteLine($"{type.Name,-28} {type.BaseType?.Name}");
}
The first three exceptions derive from IOException. The
UnauthorizedAccessException and the
OperationCanceledException, which is thrown when an operation is
cancelled, derive from SystemException.
$ dotnet run FileNotFoundException IOException EndOfStreamException IOException PathTooLongException IOException UnauthorizedAccessException SystemException OperationCanceledException SystemException
C# network streams
I/O exceptions are also thrown when we read from and write to network streams. In the following example, we connect to a web server, but we do not send any request. The server does not answer and our read operation times out.
using System.Net.Sockets;
using System.Text;
using var client = new TcpClient();
client.Connect("example.com", 80);
using NetworkStream stream = client.GetStream();
stream.ReadTimeout = 2000;
var buffer = new byte[1024];
try
{
int n = stream.Read(buffer);
Console.WriteLine(Encoding.UTF8.GetString(buffer, 0, n));
}
catch (IOException e) when (e.InnerException is SocketException se)
{
Console.WriteLine("Reading failed");
Console.WriteLine(e.Message);
Console.WriteLine(se.SocketErrorCode);
}
The ReadTimeout property sets the time in milliseconds after which
a read operation fails.
catch (IOException e) when (e.InnerException is SocketException se)
The network stream wraps the underlying SocketException in an
IOException. With an exception filter, we catch only exceptions
caused by socket errors and get the error code from the inner exception.
$ dotnet run Reading failed Unable to read data from the transport connection: Connection timed out. TimedOut
Source
In this article we have worked with I/O exceptions in C#.
Author
List all C# tutorials.