How to correctly handle this IOException? - java

public void tokenize(){
// attempt creating a reader for the input
reader = this.newReader();
while((line = reader.readLine())!=null){
tokenizer = new StringTokenizer(line);
while(tokenizer.hasMoreTokens()){
toke = (tokenizer.nextToken().trim());
this.tokenType(toke);
//System.out.println(this.tokenType(toke));
}
}
}
private BufferedReader newReader(){
try {//attempt to read the file
reader = new BufferedReader(new FileReader("Input.txt"));
}
catch(FileNotFoundException e){
System.out.println("File not found");
}
catch(IOException e){
System.out.println("I/O Exception");
}
return reader;
}
I thought I had handled it within newReader() but it appears to be unreachable. Eclipse recommends a throws but I don't understand what that's doing, or if it's even solving the problem?
Appreciate the help!

If you don't know how to handle an IOException in this method, then it means that it's not the responsibility of the method to handle it, and it should thus be thrown by the method.
The reader should be closed in this method, though, since this method opens it:
public void tokenize() throws IOException {
BufferedReader reader = null;
try {
// attempt creating a reader for the input
reader = this.newReader();
...
}
finally {
if (reader != null) {
try {
reader.close();
}
catch (IOException e) {
// nothing to do anymore: ignoring
}
}
}
}
Also, note that unless your class is itself a kind of Reader wrapping another reader, and thus has a close method, the reader shouldn't be an instance field. It should be a local variable as shown in my example.

Related

Running multiple try statements within each other?

Would this be problematic and run into issues?
Example:
try {
File Reader fileReader = new FileReader(blah);
BufferedReader bufferedReader = new BufferedReader(fileReader);
// while-statement -- extract information from blah
try {
File Reader fileReader2 = new FileReader(blah2);
BufferedReader bufferedReader2 = new BufferedReader(fileReader2);
// while-statement -- extract information from blah2
} catch (FileNotFoundException ex) {
// Display FileNotFound stuff
} catch (IOException ex) {
// Display IOException stuff
}
} catch (FileNotFoundExcpetion ex) {
// Display FileNotFound stuff
} catch (IOException ex) {
// Display IOException stuff
}
}
If it is problematic, what other approach should I look to?
Too many try-catch would complicate code and reduce the code readability which will lead to swallowing an exception and its much more worse than performance issues as it can crash your system unexpectedly.
Here is an example of swallowing an exception and its side effects (multiple point of failures like NPE etc.).
public static void main(String[] args) {
String dataFromFile = null, dataFromDataBase = null;
try {
try {
dataFromFile = readFile();
} catch (IOException e) {
// ignore exception
// String dataFromFile will be set to null
// as there was an exception
}
// imagine many lines of code here
dataFromDataBase = readDatabase(dataFromFile.getKey());
} catch (IOException e) {
// ignore exception
}
// imagine many lines of code here
System.out.println(dataFromFile.replace(" ", ""));
//imagine many lines of code here
System.out.println(dataFromDataBase.getKey());
}
private static String readFile() throws IOException {
// throws ioexception
}
private static String readDatabase(String key) throws IOException {
// throws ioexception
}
If you are expecting multiple points in a single method that can throw exceptions then club them into one try-catch and handle them appropriately. Again there can be exception to this specific question but you should always try to reduce multiple try-catch in single method.
Unless you are doing something specific with an exception, use single Exception clause to handle all exception and log details or throw it to the caller to handle it in its own specific ways.
try {
File Reader fileReader = new FileReader(blah);
BufferedReader bufferedReader = new BufferedReader(fileReader);
// while-statement -- extract information from blah
File Reader fileReader2 = new FileReader(blah2);
BufferedReader bufferedReader2 = new BufferedReader(fileReader2);
// while-statement -- extract information from blah2
} catch (Exception ex) {
// Display Exception stuff details
}
}
In this example I see no reason to start a new try statement. why not do this?
try {
File Reader fileReader = new FileReader(blah);
BufferedReader bufferedReader = new BufferedReader(fileReader);
File Reader fileReader2 = new FileReader(blah2);
BufferedReader bufferedReader2 = new BufferedReader(fileReader2);
} catch (FileNotFoundExcpetion ex) {
// Display FileNotFound stuff
} catch (IOException ex) {
// Display IOException stuff
}
But no, there would be no problem. it just looks bad. but sometimes needed I guess.

Why is eclipse complaining when I try to close BufferedReader in finally block?

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) {}
}

Try and catch blocks: whether in the class itself or when I call the method outside the class

Could you help me understand where should I throw exceptions and catch them.
Please, have a look at my code. I thought that in Thrd class I have already thrown and caught the exception. But when I wrote in the main class FirstThread.readFile("ParallelProgramming.txt");, I faced a runtime error - unhandled exception. So, I had to use try and catch. So, I somehow can't understand why in the Thd class my try and catch blocks didn't work.
package parallelprogramming;
import java.lang.Thread;
import java.io.*;
public class Thrd extends Thread {
public void readFile(String File) throws FileNotFoundException {
FileReader fr = new FileReader(File);
BufferedReader br = new BufferedReader(fr);
String s;
try {
while ((s = br.readLine()) != null) {
System.out.println(s);
}
fr.close();
}
catch (FileNotFoundException FNFD) {
System.out.println("File not found!");
}
catch (IOException IOE){
System.out.println("IOException caught!");
}
}
}
package parallelprogramming;
import java.io.FileNotFoundException;
public class ParallelProgramming {
public static void main(String[] args) throws FileNotFoundException {
Thrd FirstThread = new Thrd();
try {
FirstThread.readFile("ParallelProgramming.txt");
} catch (FileNotFoundException FNFD) {
System.out.println("File not found!");
}
}
}
The rules with checked exceptions (and this includes IOException, which FileNotFoundException is a child of), are as follows:
if you cannot, or do not want, to handle it in your current method, declare that the method throws it;
if you want to handle it in your current method, then catch it; note that even in this case you can rethrow that exception;
if main() throws any exception, and this exception triggers, the program terminates.
Now, we suppose that you are using Java 7. In this case, do that:
public void readFile(final String file)
throws IOException
{
final Path path = Paths.get(file);
for (final String line: Files.readAllLines(path, StandardCharsets.UTF_8))
System.out.println(line);
}
Why bother? ;)
If you don't want to do that but read line by line, then:
public void readFile(final String file)
throws IOException
{
final Path path = Paths.get(file);
try (
final BufferedReader reader = Files.newBufferedReader(path,
StandardCharsets.UTF_8);
) {
String line;
while ((line = reader.readLine()) != null)
System.out.println(line);
}
}
The second form is preferred if you wish to treat exceptions specifically. Note that with Java 7, you have meaningful exceptions as to why you cannot access the file vs IOException: NoSuchFileException, AccessDeniedException, etc etc. All these inherit FileSystemException. The old file API can't do that for you.
This means that if you want to deal with filesystem level errors you can do:
catch (FileSystemException e) { /* ... */ }
where before that you did:
catch (FileNotFoundException e) { /* ... */ }
Translated to the code above, if you want to catch exceptions you'll then do:
// All exceptions handled within the method -- except if you rethrow it
public void readFile(final String file)
{
final Path path = Paths.get(file);
try (
final BufferedReader reader = Files.newBufferedReader(path,
StandardCharsets.UTF_8);
) {
String line;
while ((line = reader.readLine()) != null)
System.out.println(line);
} catch (FileSystemException e) {
// deal with a filesystem-level error
// Note that you MUSt catch it before IOException
// since FileSystemException inherits IOException
} catch (IOException e) {
// deal with a low-level I/O error
}
}
Remove 'throws FileNotFoundException' from the readFile method of class Thrd then you dont need to handle this exception in main method of class ParallelProgramming.
As you throw FileNotFoundException from readFile method then exception will pass to the method will called this i.e. then main method need to handle this exception.
There are two ways to handle an exception either you need to catch it or throw it again.
In the readFile method you have done both. you caught the exceptions using catch blocks then you have mentioned that readFile method throws FileNotFoundException, so when ever you use readFile method you need to catch the exception again.

How to read line from txt?

How can I read line from text? Look at my code:
public static String getTemplateFromFile() {
String name = null;
try {
BufferedReader reader = new BufferedReader(new
FileReader(
"http://localhost:8080/blog/resources/cache/templateName.txt"));
name = reader.readLine();
//name="TEST";
//NULL anyway
reader.close();
}
catch (Exception e) {
}
return name;
}
Also I have got secnod version, but my server freeze.
public static String getTemplateFromFile() {
String name = null;
/*
try {
URL url = new URL("http://localhost:8080/blog/resources/cache/templateName.txt");
Scanner s = new Scanner(url.openStream());
name=s.nextLine();
s.close();
}
catch(IOException ex) {
ex.printStackTrace();
}*/
return name;
}
I think it can't close connection or something.
It returns me NULL even I say name="TEST"; in try construction.
FileReader is exactly that – a class that reads from files, not HTTP requests.
You're getting an invalid file path exception, which you're then ignoring in your evil empty catch block.
Instead, you should use URLConnection.
Try this
try{
URL reader=new URL("http://localhost:8080/blog/resources/cache/templateName.txt");
BufferedReader br=new BufferedReader(new InputStreamReader(reader.openStream()));
name = br.readLine();
//name="TEST";
br.close();
}catch (MalformedURLException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
AFAIK, URL#openStream() internally calls URL#openConnection() which creates an instance of URLConnection and calls URLConnection#getInputStream() on it.

Java resource management: understanding Findbugs results

Findbugs bugs me about a method which opens two Closeable instances, but I can't understand why.
Source
public static void sourceXmlToBeautifiedXml(File input, File output)
throws TransformerException, IOException, JAXBException {
FileReader fileReader = new FileReader(input);
FileWriter fileWriter = new FileWriter(output);
try {
// may throw something
sourceXmlToBeautifiedXml(fileReader, fileWriter);
} finally {
try {
fileReader.close();
} finally {
fileWriter.close();
}
}
}
Findbugs analysis
Findbugs tells me
Method [...] may fail to clean up java.io.Reader [...]
and points to the line with FileReader fileReader = ...
Question
Who is wrong: me or Findbugs?
FindBugs is correct: If the FileWriter's constructor throws an exception, the file reader will not be closed. To verify this, try passing an invalid filename for output.
I'd do it as follows:
FileReader fileReader = new FileReader(input);
try {
FileWriter fileWriter = new FileWriter(output);
try {
// may throw something
sourceXmlToBeautifiedXml(fileReader, fileWriter);
} finally {
fileWriter.close();
}
} finally {
fileReader.close();
}
Note that the handling of exception thrown when closing could be improved, since leaving a finally-block by throwing an exception will cause the try-statement to terminate by throwing that exception, swallowing any exception thrown in the try-block, which generally would be more useful for debugging. See duffymo's answer for a simple way on how to avoid this.
Edit: Since Java 7, we can use the try-with-resources statement, which permits correct and concicse handling of these corner cases:
try (
FileReader fileReader = new FileReader(input);
FileWriter fileWriter = new FileWriter(output)
) {
// may throw something
sourceXmlToBeautifiedXml(fileReader, fileWriter);
}
This may be complicated even for findbugs.
try {
fileReader.close();
} finally {
fileWriter.close();
}
Seems to me you are right.
EDIT : Wow, I thought I will get voted down for saying findbugs can be wrong!
EDIT : Looks like FindBugs is right after all. Good catch meriton.
i'd say it's you.
i'd close both resources in a separate try/catch block. i'd create static methods to help me:
public static void sourceXmlToBeautifiedXml(File input, File output)
throws TransformerException, IOException, JAXBException {
FileReader fileReader = new FileReader(input);
FileWriter fileWriter = new FileWriter(output);
try {
// may throw something
sourceXmlToBeautifiedXml(fileReader, fileWriter);
} finally {
close(fileReader);
close(fileWriter);
}
}
// same for reader & writer
public static void close(InputStream s)
{
try
{
if (s != null)
{
s.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
I think findbugs is right.
} finally {
try {
fileReader.close();
} finally {
fileWriter.close();
}
}
In this block you try to close your FileReader. This however can throw an exception and in the nested finally you close the fileWriter. Have you tried closing both readers in the same finally block? What does findbugs say then?
} finally {
try {
fileReader.close();
fileWriter.close();
} finally {
//dunno maybe log that something went wrong.
}
}

Categories