Using FileInputStream compile error says variable is uninitialized - java

Can somebody tell me what am I doing wrong in the below java code ? It doesn't compile and gives me compilation error.
import java.io.*;
public class ShowFile {
public static void main(String[] args) {
int i;
FileInputStream Fin;
try {
Fin = new FileInputStream("C:\\Users\\cbr\\Desktop\\test.txt");
} catch (FileNotFoundException exp) {
System.out.println("exception caught" + exp);
}
try {
do {
i = Fin.read();
System.out.print((char) i);
} while (i != -1);
} catch (IOException exp) {
System.out.println("Exception caught" + exp);
}
finally {
try {
Fin.close();
} catch (IOException exp) {
System.out.println("Exception caught" + exp);
}
}
}
}
while the below code compiles. You can see both initialization are within try block.
import java.io.*;
class ShowFile2 {
public static void main(String args[]) {
int i;
FileInputStream fin;
// First make sure that a file has been specified.
try {
fin = new FileInputStream("C:\\Users\\cbr\\Desktop\\test.txt");
} catch (FileNotFoundException exc) {
System.out.println("File Not Found");
return;
}
try {
// read bytes until EOF is encountered
do {
i = fin.read();
if (i != -1) {
System.out.print((char) i);
}
} while (i != -1);
} catch (IOException exc) {
System.out.println("Error reading file.");
}
try {
fin.close();
} catch (IOException exc) {
System.out.println("Error closing file.");
}
}
}

The problem is, that if new FileInputStream("C:\\Users\\cbr\\Desktop\\test.txt"); throws an exception, your variable will not be initialized in the second part of your method. This is not allowed. Object members will be initialized to null when the object is created, but this is not the case for local variables: they must be initialized explicitly.
A quick fix (but read on for a better fix) would be to initialize your variable (to null) when you are defining it:
FileInputStream fin = null;
This will solve your compilation error, however, you will get NullPointerExceptions when an exception is thrown in the first catch block.
A better solution is to put your error handling logic in the same place: if creating the FileInputStream fails, you don't want to read bytes from it anyway. So you can use a single try-catch block:
try {
fin = new FileInputStream("C:\\Users\\cbr\\Desktop\\test.txt");
// Read bytes from fin.
...
} catch (IOException e) {
// handle exception
...
}
Final advice: to make sure that your input stream is closed in all circumstances, you can use a try-with-resources block:
try (fin = new FileInputStream("C:\\Users\\cbr\\Desktop\\test.txt")) {
// Read bytes from fin.
...
} catch (IOException e) {
// handle exception
...
}

It does compile because the ShowFile2 class contains return in the catch block: this will ensure that the variable fin will be always initialized.
In the first class you caught the exception and you continue the execution of your program.

Related

Using FindBugs in eclipse

I have been using Find Bugs in Eclipse and I can not figure out why some of the bugs are coming up or how to fix them. Any ideas or help would be great!
The first bug is (Bug: Exception is caught when Exception is not thrown in banking.primitive.core.ServerSolution.saveAccounts()):
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
The second bug is (Bug: Exception is caught when Exception is not thrown in banking.primitive.core.ServerSolution.saveAccounts()):
out.writeObject(accountMap.get(i));
I tried to change it to :
out.writeObject(accountMap.get(Integer.toString(i)));
The third bug is (Bug: Exception is caught when Exception is not thrown in banking.primitive.core.ServerSolution.saveAccounts()):
} catch (Exception e) {
e.printStackTrace();
throw new IOException("Could not write file:" + fileName);
For the first bug this is with my try block as well. I am lost. I tried to follow you post below, but I am confused. Sorry, I am very new!
public ServerSolution() {
accountMap = new HashMap<String,Account>();
File file = new File(fileName);
ObjectInputStream in = null;
try {
if (file.exists()) {
System.out.println("Reading from file " + fileName + "...");
in = new ObjectInputStream(new FileInputStream(file));
Integer sizeI = (Integer) in.readObject();
int size = sizeI.intValue();
for (int i=0; i < size; i++) {
Account acc = (Account) in.readObject();
//CST316 TASK 1 CHECKSTYLE FIX
if (acc != null) {
accountMap.put(acc.getName(), acc);
}
}
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (Throwable t) {
t.printStackTrace();
}
}
}
}
See FindBugs Bug Description:
This method uses a try-catch block that catches Exception objects, but Exception is not thrown within the try block, and RuntimeException is not explicitly caught. It is a common bug pattern to say try { ... } catch (Exception e) { something } as a shorthand for catching a number of types of exception each of whose catch blocks is identical, but this construct also accidentally catches RuntimeException as well, masking potential bugs.
A better approach is to either explicitly catch the specific exceptions that are thrown, or to explicitly catch RuntimeException exception, rethrow it, and then catch all non-Runtime Exceptions, as shown below:
try {
...
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
... deal with all non-runtime exceptions ...
}

How to close a RandomAccessFile

I'm trying to close a RandomAccessFile but resource remain busy.
Code:
public boolean isOpen(RandomAccessFile f) {
try {
f.length() ;
return true ;
}
catch (IOException e) {
return false ;
}
}
this.rfmFile = new File(filePath);
try {
this.rfmRandomAccessFile = new RandomAccessFile(rfmFile, "rws");
} catch(Exception e){
}finally{
this.rfmRandomAccessFile.close();
}
while(!isOpen(this.rfmRandomAccessFile));
log.debug("I Finally Closed this RAF");
Log is not showed and thread goes in loop.
When I try to access to my resource from shell it gives me "Device or Resource busy".
The only way to access is kill java process.
When you are trying to access the RandomAccessFile length(), method, it is already closed and thus you cannot access it anymore.
You probably want to use the length() method of File. Your loop cannot work as the RandomAccessFile was already closed.
But I must admit I am clueless on the low level reason why rfmRandomAccessFile would not really be closed. It could be a side effect of your strange loop trying to get the size of a closed file.
[edit:]Could not reproduce your issue with the following piece of code:
package com.company;
import java.io.*;
public class Main {
public static void main(String[] args) {
File file = new File("foobar.txt");
RandomAccessFile randomAccessFile = null;
try {
randomAccessFile = new RandomAccessFile(file, "rws");
randomAccessFile.write(new byte[]{'f'});
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(randomAccessFile !=null){
try {
randomAccessFile.close();
} catch (IOException e) {
//doh!
}
}
}
FileReader reader = null;
try {
reader = new FileReader(file);
char read = (char) reader.read();
System.out.println("what was written: "+read);
System.out.println("file size: "+file.length());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(reader !=null){
try {
reader.close();
} catch (IOException e) {
//doh!
}
}
}
}
}

When is it required to initialize an object in java and when not?

I get error that variable fin might not have been initialized in the following program. Please clear me the concept about initialization. :
import java.io.*;
class ShowFile
{
public static void main(String args[])
throws IOException
{
int i;
FileInputStream fin;
try
{
fin=new FileInputStream(args[0]);
}
catch(FileNotFoundException e)
{
System.out.println("File not found");
}
catch(ArrayIndexOutOfBoundsException e)
{System.out.println("Array index are out of bound");}
do
{
i=fin.read();
System.out.println((char) i);
} while(i!=-1);
fin.close();
}
}
but in the following code, I don't get such error
import java.io.*;
class ShowFile {
public static void main(String args[])
{
int i;
FileInputStream fin;
// First, confirm that a file name has been specified.
if(args.length != 1) {
System.out.println("Usage: ShowFile filename");
return;
}
// Attempt to open the file.
try {
fin = new FileInputStream(args[0]);
} catch(FileNotFoundException e) {
System.out.println("Cannot Open File");
return;
}
// At this point, the file is open and can be read.
// The following reads characters until EOF is encountered.
try {
do {
i = fin.read();
if(i != -1) System.out.print((char) i);
} while(i != -1);
} catch(IOException e) {
System.out.println("Error Reading File");
}
// Close the file.
try {
fin.close();
} catch(IOException e) {
System.out.println("Error Closing File");
}
}
}
Why so ? Please help me. and sorry for the inconvenience in reading. It's my first post so I don't know that exactly how to post.
Thank you.
You have this try-catch block
try {
fin=new FileInputStream(args[0]);
} catch(...) {
.....
}
where you catch a potential FileNotFoundException then outside of it you you access fin
If an exception occurs in the first block, then fin will be uninitialized and you will end up with an NPE
Move the reading inside the first block.
try {
fin=new FileInputStream(args[0]);
do {
i=fin.read();
System.out.println((char) i);
} while(i!=-1);
} catch(...) {
.....
} finally {
if(fin != null) {
try { fin.close(); } catch(IOException e) {}
}
}
A variable needs to be initialized before it is used.
In your case, for example, this line fin=new FileInputStream(args[0]); might throw an exception (suppose, the file does not exist), you catch the exception, print it out, and then do this i=fin.read();
Here fin might not have been initialized.
In general, it is a good idea to always initialized all variables when you declare them:
int i = 0;
InputStream fin = null;
Next time, please also post the actual error message you need help with. It helps not having to try to "compile" your code mentally to guess what you are talking about.
For variables declared and not initializsed inside a method, there must not be any possible execution path from the declaration to any point of the variable's use. This is checked by the compiler, and it won't let you compule.
Fields in a class are always initiialzed, possibly with zero, so it does not apply to these.

Java, Exception when trying to deserialize object, problems catching

I have a program that needs to load data at launch. The data comes from a serialized object. I have a method loadData(), which is called upon construction of the Data class. Sometimes, (I.e. after a loss of saveData, or on first program launch on a new system), the file can be empty. (The file will exist though, the method ensures that).
When I try to run the program, I recieve an EOFException. So, in the method, I try to catch it, and just print a line to the console explaining what happened and return to the caller of the method. (so, upon return, the program will think loadData() is complete and has returned. However, it still crashes throwing the exception without printing a line to the console or anything. It is like it is totally ignoring the catch I have in place.
CODE:
protected void loadData()
{
// Gets/creates file object.
saveFileObject = new File("savedata.ser");
if(!saveFileObject.exists())
{
try
{
saveFileObject.createNewFile();
}
catch(IOException e)
{
System.out.println("Uh oh...");
e.printStackTrace();
}
}
// Create file input stream
try
{
fileIn = new FileInputStream(saveFileObject);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
// Create object input stream
try
{
inputStream = new ObjectInputStream(fileIn);
}
catch(IOException e)
{
e.printStackTrace();
}
// Try to deserialize
try
{
parts = (ArrayList<Part>)inputStream.readObject();
}
catch(EOFException e)
{
System.out.println("EOFException thrown! Attempting to recover!");
return;
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
catch(IOException e)
{
e.printStackTrace();
}
// close input stream
try
{
inputStream.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
Any help please?
Try writing your code like :
protected void loadData() {
// Gets/creates file object.
saveFileObject = new File("savedata.ser");
try {
if (!saveFileObject.exists()) {
saveFileObject.createNewFile();
}
// Create file input stream
fileIn = new FileInputStream(saveFileObject);
// Create object input stream
inputStream = new ObjectInputStream(fileIn);
// Try to deserialize
parts = (ArrayList<Part>) inputStream.readObject();
// close input stream
inputStream.close();
} catch (EOFException e) {
System.out.println("EOFException thrown! Attempting to recover!");
} catch (IOException e) {
System.out.println("Uh oh...");
e.printStackTrace();
}
}
Also note that EOFException is a sub-class of IOException
How about making one try and then making catches respectively like here?

Learning handling exceptions, can't figure out this FileNotFoundException

I'm a beginner still, and currently learning about handling exceptions. The exercise in my book I'm trying to figure out tells me to add a Finally block to close out the file I opened, and I don't understand what I'm doing wrong. Keep in mind the file name and path are fake but here is what I have:
public static String readLineWithFinally()
{
System.out.println("Starting readLineWithFinally method.");
RandomAccessFile in = new RandomAccessFile("products.ran", "r");
try
{
String s = in.readLine();
return s;
}
catch (IOException e)
{
System.out.println(e.toString());
return null;
}
finally
{
try
{
in.close();
}
catch (Exception e)
{
System.out.println("Generic Error Message");
}
}
}
To add on to Taylor Hx's answer, you can take advantage of Java 7's try-with-resources construct to avoid having to use finally altogether in your case.
public static String readLineWithFinally() {
System.out.println("Starting readLineWithFinally method.");
try (RandomAccessFile in = new RandomAccessFile("products.ran", "r")) {
return in.readLine();
} catch (IOException e) {
System.out.println(e.toString());
return null;
}
}
You'll also want to be certain that your usage is consistent with what the API mandates for RandomAccessFile.
The code that you posted shouldn't compile, as RandomFile(String, String) can possibly throw FileNotFoundException. As such, we must include it in the try block.
System.out.println("Starting readLineWithFinally method.");
RandomAccessFile in = null;
try {
in = new RandomAccessFile("products.ran", "r");
String s = in.readLine();
return s;
} catch (IOException e) {
System.out.println(e.toString());
return null;
} finally {
try {
if(in != null) {
in.close();
}
} catch (Exception e) {
System.out.println("Generic Error Message");
}
}
Keep in mind the file name and path are fake but here is what I have:
That is why you will have a FileNotFoundException while creating RandomAccessFile("products.ran", "r") with read access mode "r".
From the documentation: RandomAccessFile(String name, String mode)
This constructor throws a FileNotFoundException if the mode is
"r" but the given string does not denote an existing regular file,
or if the mode begins with "rw" but the given string does not denote
an existing, writable regular file and a new regular file of that name
cannot be created, or if some other error occurs while opening or
creating the file

Categories