C# IOException
last modified April 20, 2025
This tutorial explains how to use the IOException class in C# to handle file I/O errors. IOException represents errors that occur during input/output operations.
The IOException class is thrown when an I/O error occurs during file operations. It is the base class for more specific I/O exceptions.
IOException
handles various file system errors like missing files,
access violations, and device errors. It provides detailed error information
through its properties.
Basic IOException Handling
This example demonstrates catching an IOException when attempting to read a non-existent file. It shows basic exception handling structure.
using System; using System.IO; class Program { static void Main() { try { string content = File.ReadAllText("nonexistent.txt"); Console.WriteLine(content); } catch (IOException ex) { Console.WriteLine($"IO Error: {ex.Message}"); } catch (Exception ex) { Console.WriteLine($"General Error: {ex.Message}"); } } }
The code attempts to read a file that doesn't exist. The IOException catch block handles the specific error. The example shows a typical pattern where more specific exceptions are caught before general ones.
When the file doesn't exist, File.ReadAllText throws an IOException. The catch block captures this exception and displays its Message property. This provides the user with meaningful error information about what went wrong with the file operation.
Handling File Access Violations
This example shows how to handle IOException when file access is denied due to permissions or file locks.
using System; using System.IO; class Program { static void Main() { try { // Try to open a file that's already in use using (var fs = new FileStream("lockedfile.txt", FileMode.Open, FileAccess.ReadWrite)) { Console.WriteLine("File opened successfully"); } } catch (IOException ex) { Console.WriteLine($"Access Error: {ex.Message}"); if (ex.HResult == -2147024864) // ERROR_SHARING_VIOLATION { Console.WriteLine("The file is being used by another process"); } } } }
The code attempts to open a file that might be locked by another process. IOException catches the access violation. The example checks the HResult property to identify specific error conditions.
When a file is locked by another application, Windows prevents access. The IOException provides details about this condition. By examining the HResult value, we can determine the exact nature of the access problem. This allows for more specific error handling and user feedback.
Checking File Existence Before Operations
This example demonstrates combining File.Exists check with IOException handling for robust file operations.
using System; using System.IO; class Program { static void Main() { string filePath = "data.txt"; if (!File.Exists(filePath)) { Console.WriteLine("File does not exist"); return; } try { string content = File.ReadAllText(filePath); Console.WriteLine(content); } catch (IOException ex) { Console.WriteLine($"Error reading file: {ex.Message}"); } } }
The code first checks if the file exists before attempting to read it. This prevents some IOException cases. However, it still includes exception handling because race conditions can occur.
Between checking File.Exists and actually reading the file, the file might be deleted or become inaccessible. Therefore, IOException handling remains necessary even with existence checks. This pattern provides both proactive checking and reactive error handling.
Handling Directory Operations
This example shows IOException handling when working with directories, including cases where directories are not accessible.
using System; using System.IO; class Program { static void Main() { string dirPath = @"C:\RestrictedFolder"; try { string[] files = Directory.GetFiles(dirPath); foreach (var file in files) { Console.WriteLine(file); } } catch (IOException ex) { Console.WriteLine($"Directory Error: {ex.Message}"); } catch (UnauthorizedAccessException ex) { Console.WriteLine($"Permission Denied: {ex.Message}"); } } }
The code attempts to list files in a potentially restricted directory. IOException handles general I/O errors, while UnauthorizedAccessException catches permission issues. This shows handling multiple related exceptions.
Directory operations can fail for various reasons - the directory might not exist, the path might be invalid, or permissions might be insufficient. The example demonstrates how to handle these different scenarios with appropriate exception types while maintaining clean error reporting.
Handling Drive Errors
This example demonstrates handling IOException when dealing with drive-related errors like unavailable network drives.
using System; using System.IO; class Program { static void Main() { string filePath = @"Z:\networkfile.txt"; try { string content = File.ReadAllText(filePath); Console.WriteLine(content); } catch (IOException ex) when (ex.Message.Contains("not available")) { Console.WriteLine("Network drive not available"); } catch (IOException ex) { Console.WriteLine($"Drive Error: {ex.Message}"); } } }
The code attempts to read from a network drive that might be disconnected. The first catch uses a when clause to filter specific error messages. This shows advanced exception filtering techniques.
Network drives can become unavailable for various reasons. The example shows how to detect this specific condition while still handling other I/O errors. The when clause allows for more precise exception handling based on the error message content.
Handling File Copy Operations
This example demonstrates IOException handling during file copy operations, including disk full scenarios.
using System; using System.IO; class Program { static void Main() { string source = "largefile.dat"; string destination = "copy.dat"; try { File.Copy(source, destination, overwrite: true); Console.WriteLine("File copied successfully"); } catch (IOException ex) when (ex.Message.Contains("enough space")) { Console.WriteLine("Insufficient disk space"); } catch (IOException ex) { Console.WriteLine($"Copy Error: {ex.Message}"); } } }
The code attempts to copy a large file that might exceed available disk space. The first catch block specifically handles disk space errors. Other I/O errors are caught by the more general IOException handler.
File copy operations can fail for multiple reasons - source file not found, destination file locked, or insufficient disk space. The example shows how to distinguish between these cases while maintaining clean error handling. The when clause helps identify specific error conditions within the general IOException class.
Custom IOException Handling
This example shows how to create custom exception handling logic for specific IOException scenarios.
using System; using System.IO; using System.Runtime.InteropServices; class Program { [DllImport("kernel32.dll")] private static extern int GetLastError(); static void Main() { string filePath = "important.config"; try { using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite)) { // Work with the file } } catch (IOException ex) { int errorCode = GetLastError(); switch (errorCode) { case 32: // ERROR_SHARING_VIOLATION Console.WriteLine("File is locked by another process"); break; case 183: // ERROR_ALREADY_EXISTS Console.WriteLine("File already exists"); break; default: Console.WriteLine($"IO Error {errorCode}: {ex.Message}"); break; } } } }
The code uses Windows API to get detailed error codes for IOException. This allows for very specific error handling based on system error codes. The example demonstrates advanced integration with native Windows APIs.
By calling GetLastError after an IOException occurs, we can access the underlying system error code. This provides more detailed information than the standard exception message. The example shows how to map these error codes to specific error conditions and provide appropriate handling for each case.
Source
IOException Class Documentation
This tutorial covered handling I/O errors in C# with IOException, including file operations, directory access, and custom error handling.
Author
List all C# tutorials.