Pitfall testing a file before attempting to open it.

suggest change

Some people recommend that you should apply various tests to a file before attempting to open it either to provide better diagnostics or avoid dealing with exceptions. For example, this method attempts to check if path corresponds to a readable file:

public static File getValidatedFile(String path) throws IOException {
    File f = new File(path);
    if (!f.exists()) throw new IOException("Error: not found: " + path);
    if (!f.isFile()) throw new IOException("Error: Is a directory: " + path);
    if (!f.canRead()) throw new IOException("Error: cannot read file: " + path);
    return f;
}

You might use the above method like this:

File f = null;
try {
    f = getValidatedFile("somefile");
} catch (IOException ex) {
    System.err.println(ex.getMessage());
    return;
}
try (InputStream is = new FileInputStream(file)) {
    // Read data etc.
}

The first problem is in the signature for FileInputStream(File) because the compiler will still insist we catch IOException here, or further up the stack.

The second problem is that checks performed by getValidatedFile do not guarantee that the FileInputStream will succeed.

The third problem is that the tests are inefficient. For example, the exists, isFile and canRead calls will each make a syscall to perform the required check. Another syscall is then made to open the file, which repeats the same checks behind the scenes.

In short, methods like getValidatedFile are misguided. It is better to simply attempt to open the file and handle the exception:

try (InputStream is = new FileInputStream("somefile")) {
    // Read data etc.
} catch (IOException ex) {
    System.err.println("IO Error processing 'somefile': " + ex.getMessage());
    return;
}

If you wanted to distinguish IO errors thrown while opening and reading, you could use a nested try / catch. If you wanted to produce better diagnostics for open failures, you could perform the exists, isFile and canRead checks in the handler.

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:


Common Pitfalls:
* Pitfall testing a file before attempting to open it.

Table Of Contents
8 Arrays
10 Maps
11 Strings
25 JAXB
29 Enums
32 Audio
41 Scanner
63 Logging
75 Lists
78 Sets
89 JAX-WS
93 Common Pitfalls
96 XJC
98 Process
106 Modules
114 Applets
122 JNDI
139 JavaBean
141 Literals
144 Packages
150 JMX
153 JShell
159 Sockets
167 Enum Map
175 Hashtable
177 SortedMap