Know your core framework

By | October 24, 2014

I found some legacy code in a project that I’m working on. I felt that I must share this one. I think it is very important to know the core framework you are working with. Especially the one included with the language you are using.

In this project, we are currently using Java 7 and here is the legacy code that I found:

File file= new File(path, fileName);
try {
    InputStream is = new FileInputStream(file);

    // Get size of file.
    long length = file.length();

    // Create byte array to hold data.
    byte[] bytes = new byte[(int) length];

    // Read the bytes.
    int offset = 0;
    int numRead = 0;

    while ((offset < bytes.length) && ((numRead = is.read(bytes, offset, bytes.length - offset)) >= 0)) {
        offset += numRead;
    }

    // Close input stream.
    is.close();
    return bytes;
} catch (IOException e) {
    e.printStackTrace();
}

This code has one major issue and that is the possible resources leak. This leak is possible if an exception is thrown before the close statement is called. This can easily be fixed with a finally statement at the end.

So using a finally block it looks like this:

File file = new File(path, fileName);
InputStream is = null;
try {
    is = new FileInputStream(file);
    ...
    return bytes;
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (is != null) {
        try {
            is.close();
        } catch (IOException e) [
            e.printStackTrace();
        }
    }
}

But in Java 7 we got try-with-resources so let’s test with that:

File file = new File(path, fileName);
try(InputStream is = new FileInputStream(file)) {

    // Get size of file.
    long length = file.length();

    // Create byte array to hold data.
    byte[] bytes = new byte[(int) length];

    // Read the bytes.
    int offset = 0;
    int numRead = 0;

    while ((offset < bytes.length) && ((numRead = is.read(bytes, offset, bytes.length - offset)) >= 0)) {
        offset += numRead;
    }

    return bytes;
} catch (IOException e) {
    e.printStackTrace();
}

This is slightly better, but I still think it lacks some readability. Also I know that in Java 7 we got the new nio package with the Files class. Using that we get the following:

try {
    return Files.readAllBytes(Paths.get(path, fileName));
} catch (IOException e) {
    e.printStackTrace();
}

This is much easier to understand and we have also delegated all resource handling to the framework.

So by knowing the core framework got we could reduce the length from around 15 effective lines to just 5 lines of code. We are also guaranteed that the resources are closed afterwards.

Leave a Reply

Your email address will not be published.