I am trying to copy files using BufferedInputStream, and this error occurred when compile:
BufferedByteStreamCopy2.java:22: error: unreported exception IOException; must be caught or declared to be thrown
bin.close();
^
BufferedByteStreamCopy2.java:24: error: unreported exception IOException; must be caught or declared to be thrown
bout.close();
^
Could you help me to explain this? How can I modify the code? Many thanks!
import java.io.*;
public class BufferedByteStreamCopy2 {
public static void main(String[] args) {
BufferedInputStream bin = null;
BufferedOutputStream bout = null;
try {
FileInputStream fin = new FileInputStream(args[0]);
bin = new BufferedInputStream(fin);
FileOutputStream fout = new FileOutputStream(args[1]);
bout = new BufferedOutputStream(fout);
int c;
while ((c = bin.read()) != -1)
bout.write(c);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Not enough parameter.");
} catch (FileNotFoundException e) {
System.out.println("Could not open the file:" + args[0]);
} catch (Exception e) {
System.out.println("ERROR copying file");
} finally {
if (bin != null)
bin.close();
if (bout != null)
bout.close();
}
}
}
try/catch will catch an Exception but this doesn't apply to an exception thrown in a finally block. You need a try catch for the close() in there as well.
Note: copying a byte at a time is pretty inefficient, I assume this is just an exercise. As #EJP point out there is more read() and write() methods.
Related
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
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.
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;
}
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.
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