I'm trying to write a small program where I came to the following problem:
In one of my methods I have the following piece of code
try{
rootHuman = Human.load(scanner.next());
}catch(FileNotFoundException f){
//Missing Code
}
where I try to catch a FileNotFoundException. So looking at the function call from Human.load() we have this piece of code
public static Human load(String filename){
try{
Human human;
FileInputStream fileIn = new FileInputStream(filename);
ObjectInputStream in = new ObjectInputStream(fileIn);
human = (Human) in.readObject();
in.close();
fileIn.close();
return human;
}catch(IOException i){
i.printStackTrace();
return null;
}catch(ClassNotFoundException c){
c.printStackTrace();
return null;
}
also when trying to catch the FileNotFoundException here I get the same problem. My Problem is that the compiler tells me that this exception is never thrown, but when I execute the code I can obviously get a FileNotFoundException when the input from scanner.next() is a filename that doesn't exist. I'm kind of pointless here so any piece of advice is very much welcome.
Thanks in advance
Your compiler complains about this:
try{
rootHuman = Human.load(scanner.next());
}catch(FileNotFoundException f){
//Missing Code
}
In your Human.load method you catch a IOException, so a FileNotFoundException (witch is actually a sub-type of IOException) will never be thrown in method "load", this catch clausule will always handle it.
Remove the try catch block when calling Human.load():
rootHuman = Human.load(scanner.next());
Related
This question already has answers here:
Java return value (in try/catch clause)
(6 answers)
Closed 2 years ago.
package asasaSASA;
import java.io.*;
class FileInputTest {
public static FileInputStream f1(String fileName) {
try {
FileInputStream fis = new FileInputStream(fileName);
System.out.println("f1: File input stream created");
return fis; // I HAVE RETURN fis
}
catch (FileNotFoundException e) {
System.out.println("에러는"+e);
}
}
public static void main(String args[]) {
FileInputStream fis1 = null;
String fileName = "foo.bar";
System.out.println("main: Starting " + FileInputTest.class.getName()
+ " with file name = " + fileName);
fis1 = f1(fileName);
System.out.println("main: " + FileInputTest.class.getName() + " ended");
}
}
I want to make this code run but it said
This method must return a result of type FileInputStream
I can't understand because I made return fis. Why does it say that you have to return? I already returned it!
FileInputStream fis = new FileInputStream(fileName);
If the above line throws a FileNotFoundException then the next line of your code that will be executed is
System.out.println("에러는"+e);
which means it bypasses your return statement and that's why you are getting the compiler error.
There are many different ways to fix the compiler error and the other answers explain the different ways. I'm just answering your question, namely
Why does it say that you have to return?
I hope you understand now why you are wrong when you say
I already returned it!
Your exception handling is the problem. It's common, but bad code style: Whenever you catch an exception, the right move is to either deal with that exception, or, to ensure that you (re)throw some exception.
Log it, or print it? That is not handling an exception.
In this case, 'file not found' is not something you can be expected to handle; not unless you expand on what f1 is supposed to do (tip: Methods should be a bit more descriptive than that). Thus, throwing something is fair game. Furthermore, the very definition of f1 (presumably; that name is not particular enlightening and the method has no documentation) suggests that 'open this file' is a fundamental aspect of it, and therefore, throwing a FileNotFoundException is fair as well.
Thus:
Best solution
public static FileInputStream f1(String fileName) throws IOException {
FileInputStream fis = new FileInputStream(fileName);
System.out.println("f1: File input stream created");
return fis;
}
public static void main(String[] args) throws Exception {
String fileName = "foo.bar";
System.out.println("main: Starting " + FileInputTest.class.getName()
+ " with file name = " + fileName);
try (InputStream in = f1(fileName)) {
// you must close any resources you open using a try-with-resources
// construct; you did not do that in your code, I fixed this.
}
}
NB: your psv main can (and generally should!) be declared to throws Exception.
Alternate take
This one works in any scenario where you cannot throws the exception, or if adding that the signature makes no sense because it reflects an implementation detail and not an inherent aspect of what the method is trying to do:
public static FileInputStream f1(String fileName) {
try {
FileInputStream fis = new FileInputStream(fileName);
System.out.println("f1: File input stream created");
return fis;
} catch (IOException e) {
throw new RuntimeException("Unhandled", e);
}
}
Naturally, this is only appropriate for situations where you really don't expect that exception to occur under normal circumstances. Otherwise, either throw that exception onwards or make your own exception type and throw that instead of RuntimeException.
If you just need a ¯\(ツ)/¯ I don't really know what this means, I just want to move on and get rid of these exceptions solution: throw new RuntimeException("Uncaught", e); is correct; e.printStackTrace(); is incorrect. Update your IDE's templates.
Your method throws a checked exception which must be handled either inside of the method, or outside. Checked exception are to indicate that a problem may occur and you need to implement something to handle this scenario. Here we are worried that the file does not exist.
You have three Choices:
Return and handle value for not existing file (no exception is thrown here). So either return null, then check in main() that inputStream is not null, or return Optional<>, which is a JDK8 way to handle such scenarios.
Example:
public static FileInputStream f1(String fileName) {
try {
FileInputStream fis = new FileInputStream(fileName);
System.out.println("f1: File input stream created");
return fis;
} catch(FileNotFoundException e) {
System.out.println("Error "+e);
return null; // in case of not existing file
}
}
Wrap your checked FileNotFoundException into a custom RuntimeException. This will solve your problem with compile error, but may cause problems in the future if you will not catch this exception somewhere.
Example:
public static FileInputStream f1(String fileName) {
try {
FileInputStream fis = new FileInputStream(fileName);
System.out.println("f1: File input stream created");
return fis;
} catch(FileNotFoundException e) {
System.out.println("Error "+e);
throw new RuntimeException(e);
}
}
Instead of try-catch add this exception to your method signature:
Example:
public static FileInputStream f1(String fileName) throws FileNotFoundException{
FileInputStream fis = new FileInputStream(fileName);
System.out.println("f1: File input stream created");
return fis;
}
But if you declare a checked exception in a method at some point you will have to catch it and handle.
Option 3 is most desired.
This question already has answers here:
Closing a Java FileInputStream
(9 answers)
Closed 5 years ago.
I'm trying to become familiar with file I/O in Java. I started off by getting a lot of errors when compiling, such as error: unreported exception IOException; must be caught or declared to be thrown. So I made some changes to the code and ended up with:
public static void main(String[] args){
FileInputStream in = null;
FileOutputStream out = null;
String content = "hello";
byte[] contentBytes = content.getBytes();
try{
out = new FileOutputStream("output.txt");
out.write(contentBytes);
}catch(IOException e){
}catch(FileNotFoundException e){
}
finally{
if (out != null)
out.close();
}
}
Still, I get this error:
FileIO.java:16: error: exception FileNotFoundException has already been caught
}catch(FileNotFoundException e){
^
FileIO.java:21: error: unreported exception IOException; must be caught or declared to be thrown
out.close();
^
2 errors
Where did I "already catch" FileNotFoundException?
Because of the second error, do I need to put another try and catch statement in the finally clause to catch IOException? That seems messy and over-complicated. Am I doing something else wrong? And why doesn't java let me do what I want without forcing me to catch exceptions?
EDIT:
If I do:
public static void main(String[] args){
FileOutputStream out = null;
String content = "hello";
byte[] contentBytes = content.getBytes();
try{
out = new FileOutputStream("output.txt");
out.write(contentBytes);
}catch(FileNotFoundException e){
}catch(IOException e){
}
finally{
if (out != null)
out.close();
}
}
I get:
FileIO.java:20: error: unreported exception IOException; must be caught or declared to be thrown
out.close();
^
1 error
Where did I "already catch" FileNotFoundException?
FileNotFoundException extends IOException, which means IOException can catch FileNotFoundException exception. So, there is no point of FileNotFoundException after it.
Just reverse the order, to resolve this issue.
}catch(FileNotFoundException e){
}catch(IOException e){
}
Also, don't leave catch block blank, use them to display appropriate message, else you won't have any clue, if you got any exception.
second error, do I need to put another try and catch statement in the finally clause to catch IOException?
Yes. But, I would suggest to use try-with-resource it will take care of closing resource at the end.
As said, you should use try-with-resource instead
try (FileOutputStream out = new FileOutputStream("people.bin");)
{
out.write(contentBytes);
}
catch(FileNotFoundException e)
{
}catch(IOException e){
}
I am not really sure how the compiler let you the code. Could you please try the below code. I dont have any error when i run it.
Answer to the first question is :
Either remove FileNotFoundException line or put it above IOexception.
Answer to the second question is :
if you think that is messy, you can just duck the exception by using Throws i.e. throws IOException next to main(String[] args).
Java(compiler) pushes you to catch or declare your exceptions(using throws) because, the main purpose of Exceptions in java is not running into errors when the code is run. When an exception happens in the finally block, it leads to error and it ultimately impacts your application at run time. Have to very careful when you are closing stuff in Finally block. If you think, the code looks messy, then you can use Throws key word which solves your concern.
public static void main(String[] args){
FileInputStream in = null;
FileOutputStream out = null;
String content = "hello";
byte[] contentBytes = content.getBytes();
try{
out = new FileOutputStream("output.txt");
out.write(contentBytes);
}catch(IOException e){
}
finally{
if (out != null){
try{
out.close();
}catch(IOException e){
}
}
}
}
String outputPath = "output.txt";
String content = "hello";
byte[] contentBytes = content.getBytes();
try (FileOutputStream out = new FileOutputStream(outputPath)) {
out.write(contentBytes);
} catch (FileNotFoundException e) {
System.err.println("Failed to find the file to write to: " + outputPath);
} catch (IOException e) {
System.err.println("Failed to write to file: " + outputPath);
}
As QuakeCore mentioned FileNotFoundEception extends IOException, this is why you should catch FileNotFoundEception first.
It is a good practice to print at least some message, so you will not be surprised when there is no output and no exceptions in console / logs.
FileOutputStream implements AutoClosable interface. This why it is better to use try with resources. In this case JVM will close it automatically.
public static void main(String[] args) throws IOException{
FileOutputStream out = null;
String content = "hello";
byte[] contentBytes = content.getBytes();
try{
out = new FileOutputStream("output.txt");
out.write(contentBytes);
}catch(FileNotFoundException e){
}
finally{
if (out != null)
out.close();
}
}
Since FileNotFoundException extends IOException, then just by catching IOException you are catching all subtypes of IOException.
And regarding your second question, since `.close()` method also throws `IOException`, you can put all the IO code in a method, and have that method to throw `IOException`, then the caller can deal with the any exceptions.
for example:
private static void writeToFile() throws IOException{
FileInputStream in = null;
FileOutputStream out = null;
String content = "hello";
byte[] contentBytes = content.getBytes();
try{
out = new FileOutputStream("output.txt");
out.write(contentBytes);
}finally{
if (out != null)
out.close();
}
}
and then your main would look like this.
public static void main(String[] args){
FileInputStream in = null;
FileOutputStream out = null;
String content = "hello";
byte[] contentBytes = content.getBytes();
try{
writeToFile();
}catch(IOException e){
}
}
And have a look at tryResourceClose
I have this code but there is an error to this,
I am not good with java so I posted my problem in here... this is my code
public static void SaveFile() throws IOException{
System.out.println("Saving File!");
FileWriter toTextFile = new FileWriter("output.txt");
for(x=0;x<new_num_book;x++){
toTextFile.write(name[x]);
}
toTextFile.close();
}
blah blah
else if(option == 5){
SaveFile();
}
the problem is that netbeans declares an error in accessing the SaveFile function. Please help! Thanks
saveFile throws an IOException, you need to handle it or pass it on to the caller.
Take a look at The try Block for more details
Without more context it's hard to say what you should do. You could handle the exception within the current method...
else if(option == 5){
try {
SaveFile();
} catch (IOException exp) {
// Handle the exception, tell the user, roll back, what ever
// At the very least use exp.printStackTrace()
}
}
or declare the current method as throwing an IOException like the SaveFile method does
Your SaveFile method is also, potentially, leaving the file open...
If the file writing process fails for some reason, toTextFile.close may never be called, instead, you should take advantage of the try-finally block, for example
public static void SaveFile() throws IOException{
System.out.println("Saving File!");
FileWriter toTextFile = null;
try {
toTextFile = new FileWriter("output.txt");
for(x=0;x<new_num_book;x++){
toTextFile.write(name[x]);
}
} finally {
try {
toTextFile.close();
} catch (Exception exp) {
}
}
}
or if you're using Java 7+, you can make use of the try-with-resources functionality, for example...
public static void SaveFile() throws IOException{
System.out.println("Saving File!");
try (FileWriter toTextFile = new FileWriter("output.txt")) {
for(x=0;x<new_num_book;x++){
toTextFile.write(name[x]);
}
}
}
You may also want to have a read of Lesson: Exceptions and Code Conventions for the Java TM Programming Language, which will make it easier for people to read your code and for you to read others
I have code that looks something like:
public static void func(Reader r){
int c = r.read();
...
}
and the compiler tells me that r.read() might throw an IOException. Under what circumstances might this happen? It seems clear that something like FileNotFoundException is thrown when a file is not found, but an IOException is rather vague.
Edit:
In case it is of interest to anyone, I asked this question because I thought there must be a better way of handling the situation than just printStackTrace. However, without knowing what might cause the exception, I wasn't really sure how it should be done.
Lots of things can cause an IOException. When it gets thrown, you can print it out or check the message (Exception.getMessage()) to see what caused it.
A FileNotFoundException is a subclass of IOException, you can check the "known subclasses" list for others.
For example:
public void load(InputStream inputStream) throws IOException {
this.inputStream = inputStream;
this.properties.load(this.inputStream);
this.keys = this.properties.propertyNames();
inputStream.close();
}
I think that's when you have problem with input / output (connections) because of security or for example not opening the stream.
Code source: stackoverflow
It can throw an IOException when the either the stream itself is corrupted or some error occurred during reading the data i.e. Security Exceptions, Permission Denied etc and/or a set of Exceptions which are derived from IOEXception.
IOException is superclass of many exceptions like CharConversionException, CharacterCodingException and EOFException.
If the method listed all these exceptions then caller would have to catch all of them. So for convenience having IOException in throws clause helps callers to avoid multiple catch blocks. User can still handle specific exception if they desire so by checking for instance of or exception.getMessage().
If you want to know the specifics, in your catch block do this:
catch (IOException e)
{
e.printStackTrace();
}
This code will help you to debug and to see the IOException thrown:
String NL = System.getProperty("line.separator");
String line;
FileInputStream in;
try {
fileName = choose.getSelectedFile().getCanonicalPath();
} catch (IOException e) {
e.printStackTrace(); //This doesn't matter, see the second IOException catch.
}
try {
in = new FileInputStream(choose.getSelectedFile());
BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
StringBuffer content=new StringBuffer("");
while((line = reader.readLine()) != null){
content.append(line+NL);
}
textArea.setText(content.toString());
reader.close();
reader.readLine();
} catch (FileNotFoundException e) {
JOptionPane.showMessageDialog(new JFrame(), "The file does not exist!", "Error", JOptionPane.WARNING_MESSAGE);
} catch (IOException e) {
JOptionPane.showMessageDialog(new JFrame(), "There was an error in reading the file.", "Error", JOptionPane.WARNING_MESSAGE);
}
Good luck.
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.
}
}