Basically, I want to open a file, read some bytes, and then close the file. This is what I came up with:
try
{
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
try
{
// ...
inputStream.read(buffer);
// ...
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
try
{
inputStream.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
Maybe I'm spoiled by RAII, but there must be a better way to do this in Java, right?
If you have the same exception handling code for IOException and FileNotFoundException then you can rewrite your example in a more compact way with only one catch clause:
try {
InputStream input = new BufferedInputStream(new FileInputStream(file));
try {
// ...
input.read(buffer);
// ...
}
finally {
input.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
You can even get rid of the outer try-catch if you can propagate the exception which probably makes more sense then manually printing the stack trace. If you don't catch some exception in your program you'll get stack trace printed for you automatically.
Also the need to manually close the stream will be addressed in Java 7 with automatic resource management.
With automatic resource management and exception propagation the code reduces to the following:
try (InputStream input = new BufferedInputStream(new FileInputStream(file))) {
// ...
input.read(buffer);
// ...
}
Usually these methods are wrapped up in libraries. Unless you want to write at this level, it is best to create your own helper methods or use existing ones like FileUtils.
String fileAsString = Fileutils.readFileToString(filename);
// OR
for(String line: FileUtils.readLines(filename)) {
// do something with each line.
}
I don't know if it is the right way, but you can have all your code in the same try block, and then have the different catch blocks right after each other.
try {
...
}
catch (SomeException e) {
...
}
catch (OtherException e) {
...
}
If you want to do this in plain Java, the code you have posted looks OK.
You could use 3rd party libraries such as Commons IO, in which you would need to write much less code. e.g.
Check out Commons IO at:
http://commons.apache.org/io/description.html
Sometimes you can reduce the code to the following:
public void foo(String name) throws IOException {
InputStream in = null;
try {
in = new FileInputStream(name);
in.read();
// whatever
} finally {
if(in != null) {
in.close();
}
}
}
Of course this means the caller of foo has to handle the IOException but this should be the case most of the time anyway. In the end you don't really reduce all that much complexity but the code becomes much more readable due to less nested exception handlers.
My take on this without using utilities would be:
InputStream inputStream = null;
try {
inputStream = new BufferedInputStream(new FileInputStream(file));
// ...
inputStream.read(buffer);
// ...
} catch (IOException e) {
e.printStackTrace();
throw e; // Rethrow if you cannot handle the exception
} finally {
if (inputStream != null) {
inputStream.close();
}
}
Not a one-liner, but not pretty bad. Using, say, Apache Commons IO it would be:
//...
buffer = FileUtils.readFileToByteArray(file);
//...
The thing to rembember is that standard Java lacks many of these little utilities and easy to use interfaces that everyone needs, so you have to rely on some support libraries like Apache Commons, Google Guava, ... in your projects, (or implement your own utility classes).
Use org.apache.commons.io.FileUtils.readFileToByteArray(File) or something similar from that package. It still throws IOException but it deals with cleaning up for you.
Try the following:
try
{
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
byte[] buffer = new byte[1024];
try
{
// ...
int bytesRead = 0;
while ((bytesRead = inputStream.read(buffer)) != -1) {
//Process the chunk of bytes read
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
inputStream.close();
}
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
Google guava has tried to address this problem by introducing Closeables.
Otherwise you have to wait until AutoCloseable from JDK 7 comes out as it addresses some of the cases when IOException is thrown.
Related
Code Snippet :
InputStream inputStream = null;
try{
ExternalServiceObject object = externalService.getObject();
inputStream = object.getInputStream();
// further uses of inputStream
} catch(Exception e){
throw e;
} finally {
if(inputStream != null)
inputStream.close();
}
Here, externalService.getObject() can also throw an exception.
Wish to refactor this code using try-with-resources, hence avoiding the finally block.
Or is the current behavior the most appropriate behavior.
All the comments and answers are appreciated.
If you don't need the external service object for anything else:
try (InputStream inputStream = externalService.getObject().getInputStream()) {
// further uses of inputStream
} catch (Exception e) {
// ... logging etc
throw e;
}
I believe that execution order in the try-with-resources is top-down
(like all other java variable definitions)
try
(
ExternalServiceObject externalServiceObject = externalService.getObject(),
InputStream inputStream = externalServiceObject.getInputStream();
)
{
// further uses of inputStream
}
catch (Exception e)
{
// do stuff.
}
Caveat: ExternalServiceObject must implement AutoCloseable
So, use try-with-resources if that's what you want to use:
try {
ExternalServiceObject object = externalService.getObject();
try (InputStream inputStream = object.getInputStream()) {
// ...
}
} catch (Exception e) {
throw e; // But why catch it only to rethrow?
}
The closing of the InputStream can be done using a try-with-resources block. It is more readable and less clunky. InputStream implements AutoCloseable and thus upon exiting a try-with-resources block the class's close method will automatically be called. If you are only using the InputStream for the scope of the try-catch-finally block then you should move it to the try block.
Also, you should avoid (where possible) catching Exception. Any resulting exceptions that are thrown in your try block could result in unwanted behavior.
This question already has answers here:
java.io.FileNotFoundException when creating FileInputStream
(2 answers)
Closed 6 years ago.
For my application I want to use a Map to act as a database. To save and load a map, I am writing/reading it to/from database.ser using this 2 methods:
private synchronized void saveDB() {
try {
fileOut = new FileOutputStream(db);
out = new ObjectOutputStream(fileOut);
out.writeObject(accounts);
fileOut.close();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
#SuppressWarnings("unchecked")
private void loadDB() {
try {
fileIn = new FileInputStream(db);
in = new ObjectInputStream(fileIn); // that is where error is produced if fileIn is empty
accounts = (Map<String, Client>) in.readObject();
in.close();
fileIn.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I want to load into Map when application starts, so I invoke method in constructor like this:
protected DriveatorImpl() {
accounts = new ConcurrentHashMap<String, Client>();
db = new File("C:/Users/eduar/git/Multy-Threaded-Bank-System/Bank-Services/database.ser");
// also, any suggestions how can I make path to a file more flexible in case I want to run Server side of an app on different machine?
if (!db.exists()) {
try {
db.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
loadDB(); // loads database when server start
}
I am aware of what causing an error, but I don't know what should I change in my design to avoid ObjectInputStream constructor receiving empty stream!
Any suggestions on what I can do differently?
Edit: I want to note that in fresh application run database.ser is empty since there was no entries made into Map yet.
Thank You!
First why the EOFExcpetion occur?
There are no contents in file or file is empty and you tried to read file.
You can avoid the EOFException for an empty file by checking file content length if it is less than or equal to zero means file is empty. another way to check if file is empty
Some code change and it worked for me.
#SuppressWarnings("unchecked")
private void loadDB() {
try {
if (db.length() <= 0) {
// if statement evaluates to true even if file doesn't exists
saveDB(); // save to a file an empty map
// if file doesn't exist, it creates a new one
// call loadDB inside constructor
}
FileInputStream fileIn = new FileInputStream(db);
ObjectInputStream in = new ObjectInputStream(fileIn); // that is where error is produced if fileIn is empty
in.readObject();
in.close();
fileIn.close();
System.out.println(accounts);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Get rid of the file.exists()/file.createNewFile() crap. All it is doing for you is masking the original FileNotFoundException problem, and turning into a thoroughly predictable EOFException because of trying to construct an ObjectInputStream around an empty stream. Handle the original problem. Don't just move it, or turn it into something else.
I regularly see this style of resource clean-up:
InputStream in = null;
try {
in = new FileInputStream(file);
// ...
} finally {
if (in != null) {
in.close();
}
}
I have always used the following style:
final InputStream in = new FileInputStream(file);
try {
// ...
} finally {
in.close();
}
But am I missing something? Is there an advantage to the former that I'm not seeing?
I suspect its to avoid having two nested try/catch blocks instead of one.
InputStream in = null;
try {
in = new FileInputStream(file);
// ...
} catch(IOException ioe) {
// handle exception.
} finally {
IOUtils.closeQuietly(in);
}
The second case is incomplete.
try {
final InputStream in = new FileInputStream(file);
try {
// ...
} finally {
in.close();
}
} catch(IOException e) {
// handle exception
}
If you have multiple files, this could get really messy.
Suppose that in the first example you have some other code before defining in that gets you out of the try block. If you get to the finally without in been defined you will get a NullPointerException when trying to close it. So you will have to make the check to avoid errors like that.
This is very simple example, And may not create a problem as you are creating InputStream in same bloke. But if InputStream is closed because of some Exception or other fault, in that case your code will fail, So its always better to check if InputStream is available
The second one will not compile since the constructor of FileInputStream can throw a FileNotFoundException, thus you'd need an extra try-catch block, unless of course, the method itself throws it.
Another common idiom is to write a closeQuietly() method to avoid having to write the if (is != null) check all over your finally blocks. This is what Apache Common's IOUtils does:
public static void closeQuietly(InputStream input) {
try {
if (input != null) {
input.close();
}
} catch (IOException ioe) {
// ignore
}
}
Also note that since Java 7, you can use the following:
try (InputStream is = new FileInputStream(file)) {
} catch (final FileNotFoundException | IOException ex) {
}
The null check here for the InputStream is necessary as it is possible that the variable might not be assigned. In this case a NullPointerException would be thrown when attempting to close it when calling:
in.close();
In the 2nd block outside of the try/catch block:
final InputStream in = new FileInputStream(file);
try {
// ...
} finally {
in.close();
}
You can easily encounter other exceptions before entering the block and the InputStream is never closed.
Lets say you need to open not one, but two files. You would do
final InputStream in = new FileInputStream(file1);
final OutputStream out = new FileOutputStream(file2);
try {
// ...
} finally {
out.close();
in.close();
}
If the out fails to open, you will get an exception and because it's out of the try block in won't be closed in the finally block.
In the other method:
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(file1);
out = new FileOutputStream(file2);
// ...
} finally {
if (out != null) out.close();
if (in != null) in.close();
}
If out fails to open, you will go to the finally block and close both streams. If in fails to open, you will go to the finally block, and free only in - because out==null.
edit
As the aetheria mentioned, that code wouldn't work because close() throws exception in Java. It can easily be fixed by putting each resource release in it's own try-catch block:
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(file1);
out = new FileOutputStream(file2);
// ...
} finally {
try{ out.close(); }catch(Exception e){}
try{ in.close(); }catch(Exception e){}
}
I ditched the null checking - if in or out is null, it'll throw a NullPointerException that will be ignored. And the reason I ignore close exceptions is that disposal methods shouldn't throw exceptions in the first place. If handling closing exceptions is required, you can always close the streams again, after the finally block. That way, any stream that can be closed will be closed already(so you wouldn't have to worry about it), and you can handle any exceptions from close more elegantly.
Now, aetheria also suggested to put a separate try-finally block for each resource that would look like this:
final InputStream in = new FileInputStream(file1);
try {
final OutputStream out = new FileOutputStream(file2);
try {
// ...
} finally {
out.close();
}
} finally {
in.close();
}
This works, but even with only two resources, it's much less elegant, as it splits the allocations and releasing code, making it harder to keep track of it(in my opinion, at least).
The standard way of handling file reading and writing in java goes something like this:
try
{
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("file.dat"));
oos.writeObject(h);
oos.close();
}
catch (FileNotFoundException ex)
{
}
catch (IOException ex)
{
}
But I'm bothered by that code, because it could be possible here that the file is never closed if an exception is thrown. Sure we could add a finally clause and initialise the ObjectOutputStream outside the try block. However, when you do that you need to add another try/catch block INSIDE the finally block again...that's just ugly. Is there a better way of handling this problem?
use apache commons io
http://commons.apache.org/proper/commons-io/
look at their FileUtils class. Full of gold. Gold I say....
This is not the standard way at all. This is the bad way.
The way I use most of the time is this one :
ObjectOutputStream out = null;
try {
out = new ObjectOutputStream(new FileOutputStream("file.dat"));
// use out
}
finally {
if (out != null) {
try {
out.close();
}
catch (IOException e) {
// nothing to do here except log the exception
}
}
}
The code in the finally block can be put in a helper method, or you can use commons IO to close the stream quietly, as noted in other answers.
A stream must always be closed in a finally block.
Note that JDK7 will make it much easier with the new syntax, which will automatically close the stream at the end of the try block :
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("file.dat"))) {
// use out
}
This why I use commons-io's IOUtils.closeQuitely(...)
try
{
...
}
finally
{
IOUtils.closeQuietly(costream);
}
try
{
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("file.dat"));
oos.writeObject(h);
//oos.close(); // glow coder removed
}
catch (FileNotFoundException ex)
{
}
catch (IOException ex)
{
}
// glowcoder adds:
finally {
try {
oos.close();
}
catch(IOException ex) {
// dammit we tried!
}
}
add this finally:
finally{
if(oos != null)
oos.close();
}
Due to my company's policy of using Eclipse and using Eclipse's code-autofix, the following code pattern appears excessively in the codebase:
InputStream is = null;
try {
is = url.openConnection().getInputStream();
// .....
} catch (IOException e) {
// handle error
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
// handle error
}
}
}
IMO it's extremely fugly and hard to read, especially the portion within the finally block (is there really a need to catch 2 instances of IOException?). Is there anyway to streamline the code such that it looks cleaner?
Why do anything? It's working code. It's correct.
Leave it be.
First, about using IOUtils - may worth a shot telling your supervisors that the very application-server / Java runtime environment they might use, uses IOUtils and similar libraries itself. so in essence you're not introducing new components to your architecture.
Second, no, not really. There isn't really any way around it other than writing your own utility that will immitate IOUtils' closeQuietly method.
public class Util {
public static void closeStream(inputStream is) {
if (is != null) {
try {
is.close();
} catch (IOException e) {
// log something
}
}
}
Now your code is
InputStream is = null;
try {
is = url.openConnection().getInputStream();
// .....
} catch (IOException e) {
// handle error
} finally {
Util.closeStream(is);
}
Not a lot else to do as the IOException in the catch might have some specific processing.
See this question, use the closeQuietly() solution.
InputStream is = null;
try {
is = url.openConnection().getInputStream();
// .....
} catch (IOException e) {
// handle error
} finally {
IoUtils.closeQuietly(is);
}
// stolen from the cited question above
public class IoUtils {
public static closeQuietly (Closeable closeable) {
try {
closeable.close();
} catch (IOException logAndContinue) {
...
}
}
}
Or wait for JDK7's ARM blocks.
You could define something like this somewhere:
private static interface InputStreamCallback {
public void doIt(InputStream is) throws IOException;
}
private void with(InputStreamCallback cb) {
InputStream is = null;
// Creational code. Possibly adding an argument
try {
cb.doIt(is);
} catch (IOException e) {
// handle error or rethrow.
// If rethrow add throws to method spec.
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
// handle error or rethrow.
}
}
}
}
And invoke your code like this:
with(new InputStreamCallback() {
#Override
public void doIt(InputStream is) throws IOException {
is = url.openConnection().getInputStream();
// .....
}
});
If you declare with method static in a helper class, then you could even do an import static of it.
There's a drawback. You need to declare url final.
EDIT: creational code is not the point. You can arrange it in several ways. The callback is the point. You could isolate what you need to do there.