When catching C# IOException, how can I know what file caused the exception?

Viewed 244

Consider a C# code snippet like this (fileexcpt.py):

    static void test1()
    {
        try
        {
            string text1 = File.ReadAllText(@"dir1\text1.txt");
            string text2 = File.ReadAllText("text2.txt");
        }
        catch (IOException ex)
        {
            Console.Out.WriteLine(string.Format("Error reading file: {0}", ex.error_filename)); 
        }
    }

I hope ex.error_filename or something alike can tell me what file(filepath) caused the IO exception. Can I?

I see examples from https://docs.microsoft.com/en-us/dotnet/standard/io/handling-io-errors, but no such information found.

As for Python, it is natural, like this:

try:
    text1 = open(r"dir1\text1.txt", "r").read();
    text2 = open("text2.txt", "r").read();
except IOError as ex:
    print("Error reading file: {0}".format(ex.filename)); 
    
2 Answers

Why don't you use simply ex whose output's the first line will tell you which gives rise to the error?

try
{
    string text1 = File.ReadAllText("text1.txt");
    string text2 = File.ReadAllText("text2.txt");
}
catch (FileNotFoundException ex)
{
    // If you wish to get absolute path
    //Console.Out.WriteLine($"Error reading file: {ex.FileName}"); 
    // relative path
    Console.Out.WriteLine($"Error reading file: {ex.FileName.Substring(ex.FileName.LastIndexOf('\\') + 1)}"); 
    // No worry for the Substring exception because LastIndexOf returns -1 if not found, then plus 1 to start from 0.

}
catch (IOException ex)
{
    Console.Out.WriteLine($"Error reading file: {ex}"); 
}

You should avoid programming-by-exception where possible. And when you do need to catch exceptions then isolate the code into a single failing unit - don't catch across multiple points of failure.

Try this, as an example:

static void test1()
{
    string text1 = ReadAllTextGuarded(@"dir1\text1.txt");
    string text2 = ReadAllTextGuarded("text2.txt");
    if (text1 != null & text2 != null)
    {
        //Success
    }
}

static string ReadAllTextGuarded(string filename)
{
    try
    {
        return File.ReadAllText(filename);
    }
    catch (IOException ex)
    {
        Console.Out.WriteLine(string.Format("Error reading file: {0}", filename));
    }
    return null;
}
Related