I'm new to java and I'm trying to write this code but somehow it sees it as an error when using my variables. which has been declared ofc.
import java.io.*;
public class FileRead {
public void readCountries(String file){
try{
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("countries"));
Object obj = null;
while ((obj = inputStream.readObject()) != null) {
if (obj instanceof Country) {
System.out.println(((Country)obj).toString());
}
}
} catch (EOFException ex) { //This exception will be caught when EOF is reached
System.out.println("End of file reached.");
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
//Close the ObjectInputStream
try {
if (inputStream != null) { //////////ERROR: inputStream cannot be resolved to a variable
inputStream.close(); //////////// Same here
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
Move your inputStream declaration outside try block. If you define inside try, it is not visible outside the try block.
ObjectInputStream inputStream = null;
try{
inputStream = new ObjectInputStream(new FileInputStream("countries"));
........
}
It's pretty simple, you are trying to access a variable outside of the scope where it was declared. Here is a simplified example of your problem:
try {
int i = 0;
} catch(Exception e) {
//...
}
++i;
You see? Once the variable escapes the braces where it was declared, it's lost. In your example:
try{
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("countries"));
//...
} finally {
if (inputStream != null) { //////////ERROR: inputStream cannot be resolved to a variable
inputStream.close(); //////////// Same here
}
}
just drag inputStream outside:
ObjectInputStream inputStream = null;
try{
inputStream = new ObjectInputStream(new FileInputStream("countries"));
//...
} finally {
if (inputStream != null) {
inputStream.close();
}
}
Or even better use try-with-resources (hey, Java 7 is no longer new and fresh!)
try(ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("countries")) {
//...
}
No finally, close(), etc. needed.
You define inputStream inside the scope of the try block, and hence cannot access it outside.
You can resolve this by doing something like,
ObjectInputStream inputStream = null;
try{
inputStream = new ObjectInputStream(new FileInputStream("countries"));
...
}
i.e. defining the variable outside of the try-block and assigning it within. This way, you can access inputStream outside of the try-block.
It's a problem of variable scope.
Your inputStream variable belongs to try block that doesn't encompass the same scope as the catch or finally block causing inputStream to be undeclared in the catch or finally block. Thus, this variable is unknown within the catch block, explaining your "variable may not be initialized" shown by your IDE.
Simply, initializes your variable to null outside the first try/catch as follows:
ObjectInputStream inputStream = null;
try{
The variable is declared inside the try { ... } block, so its scope and visibility is restricted to it. You can't use it outside.
You can declare it outside the block:
ObjectInputStream inputStream = null;
try{
inputStream = new ObjectInputStream(new FileInputStream("countries"));
//...
} catch (EOFException ex) { //This exception will be caught when EOF is reached
//...
} finally {
//Close the ObjectInputStream
try {
if (inputStream != null) { //////////ERROR: inputStream cannot be resolved to a variable
inputStream.close(); //////////// Same here
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
inputstream does not exist outside the {} of your try/catch
Related
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.
Here is my code:
public static String readFile()
{
BufferedReader br = null;
String line;
String dump="";
try
{
br = new BufferedReader(new FileReader("dbDumpTest.txt"));
}
catch (FileNotFoundException fnfex)
{
System.out.println(fnfex.getMessage());
System.exit(0);
}
try
{
while( (line = br.readLine()) != null)
{
dump += line + "\r\n";
}
}
catch (IOException e)
{
System.out.println(e.getMessage() + " Error reading file");
}
finally
{
br.close();
}
return dump;
So eclipse is complaining about an unhandled IO exception caused by br.close();
Why would this cause an IO exception?
My second question is why eclipse doesn't complain about the following code:
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
try{
// open input stream test.txt for reading purpose.
is = new FileInputStream("c:/test.txt");
// create new input stream reader
isr = new InputStreamReader(is);
// create new buffered reader
br = new BufferedReader(isr);
// releases any system resources associated with reader
br.close();
// creates error
br.read();
}catch(IOException e){
// IO error
System.out.println("The buffered reader is closed");
}finally{
// releases any system resources associated
if(is!=null)
is.close();
if(isr!=null)
isr.close();
if(br!=null)
br.close();
}
}
}
I'd appreciate it if you kept the explanation in Laymen's terms if possible. Thanks for the help in advance
Both code examples should have compiler errors complaining about an unhandled IOException. Eclipse shows these as errors in both code examples for me.
The reason is that the close method throws an IOException, a checked exception, when called in the finally block, which is outside a try block.
The fix is to use a try-with-resources statement, which is available in Java 1.7+. The resources declared are implicitly closed.
try (BufferedReader br = new BufferedReader(new FileReader("dbDumpTest.txt")))
{
// Your br processing code here
}
catch (IOException e)
{
// Your handling code here
}
// no finally necessary.
Prior to Java 1.7, you need to wrap the calls to close() in their own try-catch blocks inside the finally block. It's a lot of verbose code to ensure that everything is closed and cleaned up.
finally
{
try{ if (is != null) is.close(); } catch (IOException ignored) {}
try{ if (isr != null) isr.close(); } catch (IOException ignored) {}
try{ if (br != null) br.close(); } catch (IOException ignored) {}
}
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!
}
}
}
}
}
A beginners book on Java has the following code in it. This book also explains about exceptions very well, and since I understood how exception works, I got a question about the following code.
For some reason if FileWriter class throws an exception, writer.close() wouldn't be executed. Therefore I think the best place to close the writer object is in a finally block. Even prior to this I have seen many code written like this, where the resource will be closed in the try block itself. I think there is no point in doing so. Only when there is no exception the resource will be closed.
Am I wrong? What is the best way to close resources in java. Should we never write code like the following?
public static void main(String[] args) {
try{
FileWriter writer = new FileWriter("file.txt");
writer.write("i am writing");
writer.close();
}catch(IOException e){
ex.printStackTrace();
}
}
I agree with #cyber-rookie, it is probably best to close resources in a finally block.
Java 7 introduced "try-with-resources" in order to cut down on programming mistakes...
https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
You can now write...
try (FileWriter writer = new FileWriter("file.txt")) {
writer.write("i am writing");
} catch (IOException e) {
e.printStackTrace();
}
The compiler will add the extra code to close the writer at the end of the block for you
If your are using Java 7, the best approach is to use try with resource. See https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
try (FileWriter writer = new FileWriter("file.txt")) {
writer.write("i am writing");
}
you are right, resource should be closed in finally block.
as of java 7 you can use try-with-resource also as :
try (BufferedReader br =
new BufferedReader(new FileReader(path))) {
return br.readLine();
}
Because the BufferedReader instance is declared in a try-with-resource statement, it will be closed regardless of whether the try statement completes normally or abruptly if these resources implements AutoCloseable interface.
In my experience we would utilise the finally clause of a try-catch:
public static void main(String[] args) {
FileWriter writer = null;
try {
writer = new FileWriter("file.txt");
writer.write("i am writing");
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
if (writer != null)
writer.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
PS: Place this in separate method and throw the exception, let the class using this handle exceptions.
Answer to a comment to add multiple resources in a try with resource block:
try(FileWriter writer = new FileWriter("file.txt"); BufferedReader reader = new BufferedReader(new FileReader("file.txt"))){
// you can put many AUTOCLOSEABLE objects in try with resource. Just seperate them with ";"
} catch (IOException e) {
e.printStackTrace();
}
At work (Java 6), we close the resources in the TRY block then also do a defensive close in the FINALLY block.
BufferedReader bufferedReader;
try {
//initialize and do something with the bufferedReader
bufferedReader.close();
} catch (FileNotFoundException ex) {
// notify the user
} catch (IOException ex) {
// notify the user
} finally {
if (bufferedReader != null) {
try {
//defensive close
bufferedReader.close();
} catch (IOException ex) {
// this will be thrown if bufferedReader is already closed (in Try block, so can be leave to blank
}
}
}
Hi I am learning about Exceptions in Java and I encountered a problem with this situation.
public static void main(String[] args){
String path = "t.txt";
BufferedReader br = null;
try{
br = new BufferedReader(new FileReader(path));
StringBuilder sbd = new StringBuilder();
String line = br.readLine();
while(line != null){
sbd.append(line);
sbd.append(System.lineSeparator());
line = br.readLine();
}
String result = sbd.toString();
System.out.print(result);
}catch(IOException e){
System.out.println(e.getMessage());
}finally{
if (br != null)
br.close(); //Here it says unreported exception IOException; must be caught or declared to be thrown
}
}
when I call method close() to close the bufferedReader, it says unreported exception IOException; must be caught or declared to be thrown.
I know that JAVA 7 provides a pretty easy way to do the clean-up with
try(br = new BufferedReader(new FileReader(path))){
//....
}
but prior to JAVA 7, what can I do with this situation? adding "throws IOException" right next to the main function declaration is a way to fix that but is it a little bit complicated since I have had a catch section to catch IOExceptions
You wrapped it into another try-catch
}finally{
if (br != null)
try {
br.close(); //Here it says unreported exception IOException; must be caught or declared to be thrown
} catch (Exception exp) {
}
}
Now, if you care or not is another question. To my mind, your intention here is to make all best effort to close the resource. If you want, you could use flag and set it to true in the parent catch block (indicating that any following errors should be ignored) and if it's false in the close catch block, display an error message, for example...
boolean hasErrored = false;
try {
//...
}catch(IOException e){
e.printStackTrace();
hasErrored = true;
}finally{
if (br != null)
try {
br.close(); //Here it says unreported exception IOException; must be caught or declared to be thrown
} catch (Exception exp) {
if (!hasErrored) {
// Display error message...
}
}
}
prior to JAVA 7, what can I do with this situation?
You can add a try-catch in the finally block like,
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
// Handle the IOException on close by doing nothing.
}
}
}
add another try catch block
...
if(br != null)
try{
br.close();
} catch (IOException io){
}
I generally code it thus:
} finally {
if (br != null) {
try {
br.close();
} catch(IOException ioe) {
// do nothing
}
}
}
In fact, I once wrote a util class containing methods such as closeStream(final InputStream stream), closeStream(final OutputStream stream), closeReader(final Reader reader), etc that hides all this stuff, since you end up using it all the time.
This is approximately how try-with-resources closes resources
BufferedReader br = new BufferedReader(new FileReader(path));
IOException ex = null;
try {
br.read();
// ...
} catch(IOException e) {
ex = e;
} finally {
try {
br.close(); // close quietly
} catch (IOException e) {
if (ex != null) {
ex.addSuppressed(e);
} else {
ex = e;
}
}
}
if (ex != null) {
throw ex;
}