Initializing In Try/Catch - java

I have run into quite a snag while writing my app. Here is my issue:
I am trying to initialize the file input stream like so:
FileInputStream fis
fis = openFileInput(selectedFile);
Then put this 1 line later:
byte[] input = new byte[fis.available()];
Problem is both bits of code need try/catch statements and the second block cannot recognize fis because it was initialized within a try/catch. Here is my code:
private void openFile(String selectedFile) {
String value = "";
FileInputStream fis;
try {
fis = openFileInput(selectedFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
byte[] input = new byte[fis.available()];
} catch (IOException e) {
e.printStackTrace();
}
What should I do? (Thanks in advance)

The best approach in this situation is not to catch IOException at all.
private void openFile(String selectedFile) throws IOException {
FileInputStream fis = openFileInput(selectedFile);
byte[] input = new byte[fis.available()];
It does not make sense to continue after you got FileNotFoundException

Set FileInputStream fis = null; when you first declare the variable.
You could also run your code like this because IOException will also catch the file not found exception.
String value = "";
FileInputStream fis;
try {
fis = openFileInput(selectedFile);
byte[] input = new byte[fis.available()];
} catch (IOException e) {
e.printStackTrace();
}

Set the FileInputStream to a temporary value. null would be the best option, as in:
FileInputStream fis = null;
The reason for this is because if your try statement throws an error, then the fis will never me initialized. Then you'll have problems. If you don't exit the thing entirely, you should also add the statement after the try/catch blocks that tests if the value is null, just so that the program does not throw a null pointer exception.
So maybe something like:
if(fis == null) {
return; // Which will just end the method.
}
Also might want to put the try/catches together (you should still declare the other stuff outside of the try, at least anything you plan on using directly later on in the code) but it just might be more efficient coding wise), as in:
FileInputStream fis = null;
byte[] input = null;
try {
fis = openFileInput(selectedFile);
input = new byte[fis.available()];
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

Related

End of File Exception on ObjectInputStream.readObject

My application streams twitter data and writes them to files.
while(true){
Status status = queue.poll();
if (status == null) {
Thread.sleep(100);
}
if(status!=null){
list.add(status);
}
if(list.size()==10){
FileOutputStream fos = null;
ObjectOutputStream out = null;
try {
String uuid = UUID.randomUUID().toString();
String filename = "C:/path/"+topic+"-"+uuid+".ser";
fos = new FileOutputStream(filename);
out = new ObjectOutputStream(fos);
out.writeObject(list);
tweetsDownloaded += list.size();
if(tweetsDownloaded % 100==0)
System.out.println(tweetsDownloaded+" tweets downloaded");
// System.out.println("File: "+filename+" written.");
out.close();
} catch (IOException e) {
e.printStackTrace();
}
list.clear();
}
I have this code which gets data from files.
while(true){
File[] files = folder.listFiles();
if(files != null){
Arrays.sort(//sorting...);
//Here we manage each single file, from data-load until the deletion
for(int i = 0; i<files.length; i++){
loadTweets(files[i].getAbsolutePath());
//TODO manageStatuses
files[i].delete();
statusList.clear();
}
}
}
The method loadTweets() does the following operations:
private static void loadTweets(String filename) {
FileInputStream fis = null;
ObjectInputStream in = null;
try{
fis = new FileInputStream(filename);
in = new ObjectInputStream(fis);
statusList = (List<Status>) in.readObject();
in.close();
}
catch(IOException | ClassNotFoundException ex){
ex.printStackTrace();
}
}
Unfortunately, I don't know why sometimes it throws a
EOFException
when running this line
statusList = (List<Status>) in.readObject();
Anybody knows how I can solve this? Thank you.
I've seen that you're passing the file correctly with the getAbsolutePath() based on a previous question of yours
From what I've read that can be a couple of things, one of them the file being null.
Explaining this idea, you might have written the file but something caused the file to have nothing inside, this might cause an EOFException. The file in fact exists it's just empty
EDIT
Try to enclose the code in while(in.available() > 0)
It would look like this
private static void loadTweets(String filename) {
FileInputStream fis = null;
ObjectInputStream in = null;
try{
fis = new FileInputStream(filename);
in = new ObjectInputStream(fis);
while(in.available() > 0) {
statusList = (List<Status>) in.readObject();
}
in.close();
}
catch(IOException | ClassNotFoundException ex){
ex.printStackTrace();
}
}
Found out what was necessary to solve this. Thanks to #VGR's comment, I thought to pause the executing thread for 0.2 seconds if the file has been created less than a second ago.
if(System.currentTimeMillis()-files[i].lastModified()<1000){
Thread.sleep(200);
This prevents the exception and the application works now fine.

Java, closing inline streams

Edit: forgot to mention I'm using java 6
I was wondering about how to close resources in java.
See, I always have initialized streams like this:
ZipInputStream zin = null;
try {
zin = new ZipInputStream(new BufferedInputStream(new FileInputStream(file)));
// Work with the entries...
// Exception handling
} finally {
if (zin!=null) { try {zin.close();} catch (IOException ignored) {} }
}
But, if an exception is thrown in new ZipInputStream(...), would the opened streams in new BufferedInputStream and underliying FileInputStream be leaked?
If they are, what would be the most efficient way to ensure the resources are closed?, should I have to keep a reference to each new ...Stream and close them also in the finally block?, or should the final stream (ZipInputStream in this case) instantiated in some other way?.
Any comments are welcome.
You can do
try (InputStream s1 = new FileInputStream("file");
InputStream s2 = new BufferedInputStream(s1);
ZipInputStream zin = new ZipInputStream(s2)) {
// ...
} catch (IOException e) {
// ...
}
Further reading: The Java™ Tutorials: The try-with-resources Statement.
It can be done in this way:
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
try {
ZipInputStream zin = new ZipInputStream(bis);
try {
zin = ;
// Work with the entries...
// Exception handling
} finally {
zin.close();
}
} finally {
bis.close();
}
And you can add error caching where you want.
First lets take a look at what you have and what can go wrong with it:
try {
zin = new ZipInputStream(new BufferedInputStream(new FileInputStream(file)));
// Work with the entries...
// Exception handling
} finally {
if (zin!=null) { try {zin.close();} catch (IOException ignored) {} }
}
a.) new FileInputStream() throws, zin will not be assigned. Nothing to close in this case. Ok.
b.) new BufferedInputStream() throws (possibly OutOfMemoryError), zin not assigned. Leaked FileInputStream(). Bad.
c.) new ZipInputStream() throws, zin will not be assigned. BufferedInputStream and FileInputStream to close. Closing either would be enough. Bad.
Whenever you wrap one stream into another, you are in danger of leaking the stream youre wrapping. You need to have a reference to it and close it somewhere.
A viable way top this is to declare a single InputStream variably to hold the last create stream (or in other words, the outermost of the nested streams):
InputStream input = null;
try {
input = new FileInputStream(...);
input = new BufferedInputStream(input);
input = new ZipInputStream(input);
ZipInputStream zin = (ZipInputStream) input;
// work here
} finally {
if (input != null)
try { input.close(); } catch (IOException ignored) {}
}
This works, because if any of the new *Stream() throws, the variable input is still keeping track of the stream created before. The ugly cast from input to ZipInputStream is necessary, because you must declare input to be a type assignment compatible to all streams created.
Yes, an Exception in new ZipInputStream() or new BufferedInputStream() would leak the enclosed Streams, unless you do a cascading check in the exception handling:
FileInputStream fin = null;
BufferedInputStream bin = null;
ZipInputStream zin = null;
try {
fin = new FileInputStream(file);
bin = new BufferedInputStream(fin)
zin = new ZipInputStream(bin);
// Work with the entries...
// Exception handling
} finally {
try {
if (zin!=null) {
zin.close();
} else if (bin != null) {
bin.close();
} else if (fin != null) {
fin.close();
}
} catch (Exception e) {
// ignore
}
}
However, since BufferedInputStream and ZipInputStream are mere wrapper around the FileInputStream the probability of an Exception is rather low. If at all, an Exception if most likely to happen once you start reading and processing data. And in that case zin is created, and a zin.close() will suffice.

Is there a way to catch exceptions without breaking loop in Java?

In Java, there's a difference between a loop surrounded with a try-catch block if an exception could be thrown inside the while loop, and a statement surrounded by a try-catch block inside a loop.
For instance, the following code snippets are different:
Snippet 1:
try {
for (File file : files) {
FileInputStream fis = new FileInputStream(file);
System.out.println("OK!");
}
}
catch (FileNotFoundException exc) {
System.out.println("Error!");
}
^This code snippet breaks the loop if a FileNotFoundException is thrown. So if a file cannot be read, then the loop breaks and Java will stop reading further files.
Snippet 2:
for (File file : files) {
try {
FileInputStream fis = new FileInputStream(file);
System.out.println("OK!");
}
catch (FileNotFoundException exc) {
System.out.println("Error!");
}
}
^This code snippet does not break the loop if an exception is thrown, if an exception occurs, the code catches the exception and continues to the next element in files. With other words, it won't stop reading the files.
Now I want to read a certain file in a directory (say bananas.xml), and, unregarded if that file is readable or not—the XML file is a metadata file, which might not be required for the program to run—, read the corresponding directory (which is bananas):
File main = new File("/home/MCEmperor/test");
File fruitMeta = new File(main, "bananas.xml");
FileInputStream fruitInputStream = new FileInputStream(fruitMeta); // This code COULD throw a FileNotFoundException
// Do something with the fruitInputStream...
File fruitDir = new File(main, "bananas");
if (fruitDir.exists() && fruitDir.canRead()) {
File[] listBananas = fruitDir.listFiles();
for (File file : listBananas) {
FileInputStream fis = new FileInputStream(file); // This code COULD throws a FileNotFoundException
// Do something with the fis...
}
}
Now two lines in the snippet above may throw a FileNotFoundException and I don't want to break the loop.
Now is there a way to make one try-catch block with catches both lines if an exception is thrown, but without breaking the for-loop?
How about something like this?
FileInputStream fruitInputStream = getFileInputStream(fruitMeta);
...
fis = getFileInputStream(file);
private static FileInputStream getFileInputStream(File file) {
try {
return new FileInputStream(file);
catch(FileNotFoundException e) {
return null;
}
}

Proper try catch design

Which would be considered more proper technique for implementing a try/catch in Java:
A:
Date lastMod = null;
BufferedReader inFile = null;
try {
inFile = new BufferedReader(new FileReader("C:\\Java\\settings.ini"));
try {
lastMod = new Date(Long.parseLong(inFile.readLine()));
} catch (IOException e) {
e.printStackTrace();
}
} catch(FileNotFoundException e) {
e.printStackTrace();
}
or B:
Date lastMod = null;
BufferedReader inFile = null;
try {
inFile = new BufferedReader(new FileReader("C:\\Java\\settings.ini"));
lastMod = new Date(Long.parseLong(inFile.readLine()));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Also, is it wrong to follow the try/catch block with a long block of code that makes use of the BufferedReader, or is it preferred to include the long block of code inside the try/catch?
For example:
public static void main(String[] args) {
Date lastMod = null;
BufferedReader inFile = null;
try {
inFile = new BufferedReader(new FileReader("C:\\Java\\settings.ini"));
lastMod = new Date(Long.parseLong(inFile.readLine()));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//Long block of code using inFile
inFile.readLine();
inFile.close();
Versus:
public static void main(String[] args) {
Date lastMod = null;
BufferedReader inFile = null;
try {
inFile = new BufferedReader(new FileReader("C:\\Java\\settings.ini"));
lastMod = new Date(Long.parseLong(inFile.readLine()));
//Long block of code using inFile
inFile.readLine();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
inFile.close();
}
B is much more readable, when there is nothing going on after the internal try block, before the external try block. If you have logic to perform in between, then you must use A
In the second example the second version using finally is critical to ensure that close will be called no matter what (even if the function returns first) The first version without finally is actually wrong, since you may use up all the file handles and be unable to open more files.
As an additional note, you may need to check for null when calling close. And if you are using java 7, it's even better to use "try with resources".
For the first question: the solution A add unnecessary complexity. Use B or, if you are using Java 7, try-with-resources:
Date lastMod = null;
try (BufferedReader inFile = new BufferedReader(new FileReader("C:\\Java\\settings.ini"))){
lastMod = new Date(Long.parseLong(inFile.readLine()));
} catch (FileNotFoundException | IOException e) {
e.printStackTrace();
}
For the second question: in the first version, what if the BufferedReader creation throws an exception? You would use brafter which is null and would throw a NullPointerException. Also if something else happen, you will not have called inFile.close(), so you really need a finally. For all these reasons, again, the second solution is better.
If you are using try-with-resouces (Java 7), of course, you don't need a finally block to release your BufferedReader.
Proper technique might also include not catching your exceptions, but allowing them to bubble up to a caller instead. Do always use a finally block to clean up any state that might otherwise use up resources, but you'll often be better off catching the exception in the parent routine rather than the child routine in which the exception was thrown.
In general, if it would be helpful to know in the calling routine whether the sub-routine succeeded or not, then that sub-routine should not catch its exceptions, but should allow them to bubble up to their caller.

Stream Object Initialization

Now I am getting compile time error at line 30 and 38 that 'fin' might not have been initialized. but its perfectly to write it this way
import java.io.*;
class CopyFile {
public static void main(String args[]) throws IOException {
int i;
FileInputStream fin;//can't it be done like this?
FileOutputStream fout= new FileOutputStream(args[1]);
try{
//open input file
try{
fin = new FileInputStream(args[0]);
}
catch(FileNotFoundException e){
System.out.println("Input file Not Found");
return;
}
//open output file
try{
fout = new FileOutputStream(args[1]);
}
catch(FileNotFoundException e){
System.out.println("Error Opening File");
}
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println("usage: Copyfile From to");
}
try{
do{
i = fin.read();
if(i!= -1)
fout.write(i);
}while(i != -1);
}
catch(IOException e){
System.out.println("file error");
}
fin.close();
fout.close();
}
}
I have seen it many time initialized like this. I think its due to the try blocks.
it might miss the initialization due to being in the try block and hence the error?
The problem is that you're not initializing the FileInputStream fin at all. Your code will look like this to the compiler:
FileInputStream fin;
try {
fin = ...
//more code goes here...
} catch (...) {
//exception handling...
} finally {
fin.close(); //fin is not even null for the compiler
}
In order to make the code work, initialize it at least with a null value and check if fin != null before using the close method.
FileInputStream fin = null;
try {
fin = ...
//more code goes here...
} catch (...) {
//exception handling...
} finally {
if (fin != null) {
fin.close(); //fin is not null, at least the JVM could close it
}
}
More info:
Java: Declaring Variables
Uninitialized variables and members in Java
FileInputStream fin=null;
Assign it null or FileInputStream object.
Local variable need to be assigned to some value before being used.
Though in the first try block, you are initializing fin as fin = new FileInputStream(args[0]);, your nested statements confuse the compiler. Just update your declaration as below:
FileInputStream fin = null;
Dont use try catch for an if and vice versa.
Try/catch is for when things go wrong behind your control and that is no part of normal program flow for example writing to a hard disk that is full....
Use if for normal error checking
In your example check your args array with an if block and then initialize your fin.

Categories

Resources