views:

2469

answers:

3

FileNotFoundException is thrown on all sorts of occasions - not necessarily only when the file name is invalid, but also when e. g. permissions do not allow a file to be created or read:

java.io.FileNotFoundException: \\server\share\directory\test.csv (Anmeldung fehlgeschlagen: unbekannter Benutzername oder falsches Kennwort)
    at java.io.FileOutputStream.open(Native Method)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:179)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:131)
    at java.io.FileWriter.<init>(FileWriter.java:73)

The above example shows a German Windows complaining about invalid username or password.

Is there a way short of parsing the exceptions message to get a little finer grained information on why exactly the exception occurred? Problem with message parsing is that in different locales the messages will vary.

+1  A: 

One approach is to look at the actual type of the exception: as you can see from the docs, there are a lot of subclasses that provide finer-grained information.

However, you probably won't get far with that. As with most checked exceptions, it's usually better to log/report the exception and ask the user for choices on how to correct it.

kdgregory
Problem is I get a FileNotFoundException, not a generic IOException. I'd like to present a better user message than "File Not Found" or "Generic Error", pointing the user towards the permission problem...
Daniel Schneller
My mistake - I read IOException. Unfortunately, Java exceptions rarely have additional information (such as a POSIX error code), and in many cases are stretched to cover conditions that have little relationship to their name (sometimes due to assignment of POSIX code to exception type, sometimes, I think, due to laziness).
kdgregory
+2  A: 

You may want to look at the properties of the file using the java.io.File object before attempting to read the file. There's a canRead method on that you can use to determine whether or not the user can read the file.

Chris Gow
+4  A: 

Do the check for file existence/read-write permissions yourself before creating FileOutputStream.

File test_csv = new File( "\\server\share\directory\test.csv" );

if ( test_csv.exists( ) && test_csv.canWrite( ) )
{
  // Create file writer
  ...
}
else
{
  // notify user
  ...
}

Notice that sometimes you will have to check the read/write permissions on a parent of you destination file, if you need to create a new file.

File test_csv = new File( "\\server\share\directory\test.csv" );
File parent_dir = test_csv.getParentFile( )

if ( parent_dir.exists( ) && parent_dir.canWrite( ) )
{
  // Create file writer
  ...
}
else
{
  // notify user
  ...
}
Alexander Pogrebnyak
D'Oh! Sometimes life can be sooo easy. Thanks for opening my eyes to the obvious.
Daniel Schneller
Be careful. There are apparently some bugs that can affect the return result of these methods. You may get invalid results if your directory is a custom or system directory or if it is on certain types of network share.
Michael Rutherfurd
Apparently I just got bit by http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4939819 which will tell you that the user's home directory (documents and settings...) on Windows is not writable. Workaround: Try creating a temp file in the parent folder and delete it immediately afterwards, if successful. If an IOException is thrown, you really cannot write.
Daniel Schneller