When I was trying to close the BufferedReader in the while loop, it will throws an IOException: Stream closed when the loop execute the second time.
My code is like:
import java.io.*;
class Test {
public static void main(String[] args) {
int option = 0;
BufferedReader br = null;
while (option != -1) {
try {
br = new BufferedReader(new InputStreamReader(System.in));
try {
option = Integer.parseInt(br.readLine());
} catch (NumberFormatException e) {
option = -1;
}
br.close();
} catch (IOException e) {
System.err.println(e);
System.exit(-4);
}
System.out.println(option);
}
}
}
What should I do to close BufferedReader? Thanks in advance.
How can I close BufferedReader in the while loop
You are closing it in the while loop, and that's the problem.
Open it before the loop, and don't close it at all, as it's wrapped around System.in, which can't be reopened.
You can do a couple of things
try {
br = new BufferedReader(new InputStreamReader(System.in));
try {
option = Integer.parseInt(br.readLine());
} catch (NumberFormatException e) {
option = -1;
}
br.close();
} catch (IOException e) {
System.err.println(e);
br.close();
System.exit(-4);
}
}
If you're using a recent enough version
try {
br = new BufferedReader(new InputStreamReader(System.in));
try {
option = Integer.parseInt(br.readLine());
} catch (NumberFormatException e) {
option = -1;
}
} catch (IOException e) {
System.err.println(e);
System.exit(-4);
} finally {
br.close();
}
If an exception is incurred, the code will progress immediately to the catch statement, and then the finally statement if it exists.
Also, the whole point of exception handling is to take care of a exception that might happen. You normally wouldn't want to exit a system in an exception--since the code will terminate if you didn't handle the exception anyways.
Related
I am trying to read a file but it is asking for two try-catch blocks, one for opening a file and another for reading its content. Why is this required?
String line = null;
try {
File file = new File("F:\\Mobile Extractor.txt");
BufferedReader reader = new BufferedReader(new FileReader(file));
while((line=reader.readLine())!=null) {
System.out.println(line);
}
reader.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Consider using finally block for avoiding memory leaks and closing the streams if you are using versions before 7. From Java 7 on wards you can use try with resources is the best practice
String line = null;
File file = new File("F:\\Mobile Extractor.txt");
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(file));
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(reader!=null){
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
Try-with-Resources:
String line = null;
File file = new File("F:\\Mobile Extractor.txt");
try(BufferedReader reader = new BufferedReader(new FileReader(file));) {
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
The declaration statement appears within parentheses immediately after the try keyword. The class BufferedReader, in Java SE 7 and later, implements the interface java.lang.AutoCloseable. 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 (as a result of the method BufferedReader.readLine throwing an IOException).
Try java8, you will not require anything. You can simply do it like this.
import java.nio.file.Files;
import java.nio.file.Paths;
Files.lines(Paths.get(path))
.filter(l -> l.contains(searchWord)).forEach(System.out::println);
The try-catch block is required for IOException.
It will check for the contents available in the file. If there are no contents, then IOException would be thrown else the contents will be displayed.
It should be like:
String line = null;
try {
File file = new File("F:\\Mobile Extractor.txt");
BufferedReader reader = new BufferedReader(new FileReader(file));
try {
while((line=reader.readLine())!=null)
{
System.out.println(line);
}
} catch(IOException ex)
{
System.out.println(ex.getMessage());
}
reader.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
In the method getFileName() created the object BufferedReader and assigned reference to the object to the variable - reader. Then stream closed in the finally.
Then invoked the method readStringsFromConsole(). There creates the same object. But thrown IOException. Why did it happen ?
ps: sorry for my English :)
stacktrace:
java.io.IOException: Stream closed
at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:170)
at java.io.BufferedInputStream.read(BufferedInputStream.java:336)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at com.test.home04.Solution.readStringsFromConsole(Solution.java:55)
code:
import java.io.*;
import java.util.*;
public class Solution
{
public static void main(String[] args)
{
String fileName = getFileName();
ArrayList<String> listStrings = readStringsFromConsole();
writeToFileFromList(fileName, listStrings);
}
public static void writeToFileFromList (String fileName, ArrayList<String> listInputString)
{
PrintWriter writer = null;
try {
writer = new PrintWriter(fileName, "UTF-8");
for (String stringItem : listInputString)
writer.write(stringItem);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (writer != null)
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static ArrayList<String> readStringsFromConsole() {
BufferedReader reader = null;
ArrayList<String> listInputString = new ArrayList<String>();
String line = null;
try {
reader = new BufferedReader(new InputStreamReader(System.in));
while (true)
{
line = reader.readLine();
if ("exit".equals(line))
break;
listInputString.add(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null)
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
return listInputString;
}
}
public static String getFileName()
{
BufferedReader reader = null;
String fileName = null;
try {
reader = new BufferedReader(new InputStreamReader(System.in));
while (fileName == null) {
fileName = reader.readLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null)
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
return fileName;
}
}
}
If you create a reader from System.in and close it, it also closes System.in, which can't be opened again even if you create another reader.
In short - don't close readers which are created from System.in.
Also as Andreas pointed out in the comment, the general guideline should be that System.in should only ever be wrapped once in the lifetime of the command-line program (whether by Scanner, BufferedReader, or something else), and it should never be closed. The wrapping should likely occur at the beginning of main(), and the wrapper object should either be passed around or stored in a field (static or instance).
Why did it happen ?
It happened because you closed System.in in your getFilename method.
Why not open the stream after the close?
Basically, because you can't, or if you are asking about the behavior of the JVM ... >>it<< can't.
When close() is called, the close gets sent to the operating system which closes and releases the underlying file descriptor. Once closed, the OS does not have enough information to reopen the previous file. And if the file descriptor was for an (unnamed) pipe or socket stream, then the connection cannot be remade because:
the application or service at the other end will typically have gone away,
in the case of a TCP/IP socket, the protocol does not allow reconnection.
In short: don't close a stream if you need to read or write more from / to it later, and avoid closing System.{in,out,err} entirely.
Now if your application had a filename or a host / port, it could open a new FileReader or connect a new socket. But in the case of the System.* streams, that information is not available to the application (or the JVM).
But in your particular case, I suspect that your intention is that getFileName returns the filenames supplied one at a time; i.e. each call returns the next filename. If that is the case, you will have to implement it differently:
It shouldn't close the stream or the reader.
It shouldn't open the reader (probably).
It should return the first (or next) line that it reads rather than reading all lines and returning the last one, as it currently does.
You are closing the stream from System.in. Closed stream needs to be opened before reusing it. Don't close them if you create them from System.in.
Try this,
import java.io.*;
import java.util.*;
public class Solution
{
public static void main(String[] args)
{
String fileName = getFileName();
ArrayList<String> listStrings = readStringsFromConsole();
writeToFileFromList(fileName, listStrings);
}
public static void writeToFileFromList (String fileName, ArrayList<String> listInputString)
{
PrintWriter writer = null;
try {
writer = new PrintWriter(fileName, "UTF-8");
for (String stringItem : listInputString)
writer.write(stringItem);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (writer != null)
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static ArrayList<String> readStringsFromConsole() {
BufferedReader reader = null;
ArrayList<String> listInputString = new ArrayList<String>();
String line = null;
try {
reader = new BufferedReader(new InputStreamReader(System.in));
while (true)
{
line = reader.readLine();
if ("exit".equals(line)) {
break;
}
listInputString.add(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null)
//do not close the stream
//reader.close();
} catch (Exception e) {
e.printStackTrace();
}
return listInputString;
}
}
public static String getFileName()
{
BufferedReader reader = null;
String fileName = null;
try {
reader = new BufferedReader(new InputStreamReader(System.in));
while (fileName == null) {
System.out.println("Enter a file name: ");
fileName = reader.readLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null)
//do not close the stream
//reader.close();
} catch (Exception e) {
e.printStackTrace();
}
return fileName;
}
}
}
Hey guys I've been working on some buttons for my GUI, and I decided to implement some previous code.
However, I'm getting an error when I try to compile. In line 141 in my code (specifically, the last button) I am told that I have an unreported IOException that must be caught or declared to be thrown.
My code is below:
public void actionPerformed(ActionEvent ae) {
if ((ae.getSource() == button5) && (!connected)) {
try {
s = new Socket("127.0.0.1", 2020);
pw = new PrintWriter(s.getOutputStream(), true);
} catch (UnknownHostException uhe) {
System.out.println(uhe.getMessage());
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
}
connected = true;
t = new Thread(this);
//b.setEnabled(false);
button5.setLabel("Disconnect");
t.start();
} else if ((ae.getSource() == button5) && (connected)) {
connected = false;
try {
s.close(); //no buffering so, ok
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
}
//System.exit(0);
button5.setLabel("Connect");
} else {
temp = tf.getText();
pw.println(temp);
tf.setText("");
}
if (ae.getActionCommand().equals("Save it")) {
Scanner scan = new Scanner(System.in);
try {
PrintWriter pw = new PrintWriter(new FileWriter(new File("test.txt")));
for (;;) {
String temp = scan.nextLine();
if (temp.equals("")) {
break;
}
pw.println(temp);
}
pw.close();
} catch (IOException ioe) {
System.out.println("IO Exception! " + ioe.getMessage());
}
} else if (ae.getActionCommand().equals("Load it")) {
Scanner scan = new Scanner(System.in);
try {
BufferedReader br = new BufferedReader(new FileReader(new File("test.txt")));
String temp = "";
while ((temp = br.readLine()) != null) {
System.out.println(temp);
}
br.close();
} catch (FileNotFoundException fnfe) {
System.out.println("Input file not found.");
} catch (IOException ioe) {
System.out.println("IO Exception! " + ioe.getMessage());
}
} else if (ae.getActionCommand().equals("Clear it")) {
ta.setText("");
} else {
PrintWriter pw = new PrintWriter(new FileWriter(new File("test.txt")));
}
}
just add a try/catch block to the following code (end of what you posted):
else{
PrintWriter pw = new PrintWriter (
new FileWriter(
new File("test.txt")));
}}
like so:
else{
try{
PrintWriter pw = new PrintWriter (new FileWriter(new File("test.txt")));
} catch (Exception e) {
e.printStackTrace();
}
}}
In general, any IO operation can potentially cause an exception. Depending on what you want, the easiest solution is just put throws IOException at the top of the method where you see the problem, but this isn't very good practice, and doesn't work in this case. Putting a try/catch block around the problem line, and including a meaningful error message, is probably the best way to go.
I have a code snippet I am working on:
public void readFile()
{
BufferedReader reader = null;
BufferedReader reader2 = null;
try
{
reader = new BufferedReader(new FileReader("C:/Users/user/Desktop/testing.txt"));
reader2 = new BufferedReader(new FileReader("C:/Users/user/Desktop/testNotThere.txt"));
}
catch (FileNotFoundException e)
{
System.err.println("ERROR: FILE NOT FOUND!\n");
}
String line = null;
try {
while ((line = reader.readLine()) != null)
{
System.out.print(line);
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
And while I understand what the first exception the snippet detects: catch (FileNotFoundException e), I am looking to understand what the second exception is looking for while printing the lines of the text file:
catch (IOException e)
{
e.printStackTrace();
}
Can anyone explain what this second exception is looking for? Furthermore, how can I test to make sure this exception will be thrown in the snippet like I did with creating a second BufferedReader reader2?
IOException is thrown when your program is interrupted while reading the file.
As you may see, IO stands for "Input/Output" which means reading and writing data on disk.
So an exception of that kind means that the system crashed while while doing a reading/writing.
Source: http://docs.oracle.com/javase/7/docs/api/java/io/IOException.html
I am stuck on something very basic. In our game we have a leveleditor/loader that can fetch levels via URL. Now if the URL points to a nonexistant file the editor should refuse to load the level and simply stay in its currentlevel, I am just struggling with the basic code.
private void loadLevel(URL url) {
Scanner in = null;
try {
in = new Scanner(new BufferedReader(new InputStreamReader(
url.openStream())));
readLine(in);
in.close();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Essentially, if FileNotFound is thrown (or any other) readLine(in) should NOT proceed. All kinds of NPE if it does.
private void loadLevel(URL url) {
Scanner in = null;
try {
in = new Scanner(new BufferedReader(new InputStreamReader(
url.openStream())));
/*if(in!=null){
readLine(in);
in.close();
}*/
readLine(in);
in.close();
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
EDIT: After #LuiggiMendoza's suggestion.
Use throws and finally. Let the calling function handle it. I haven't tested it, but this sort of thing is the idea...
private void loadLevel(URL url) throws IOException, FileNotFoundException {
Scanner in = null;
try {
in = new Scanner(new BufferedReader(new InputStreamReader(
url.openStream())));
if (in == null) throw new FileNotFoundException();
readLine(in);
}
finally {
in.close();
}
}
On the context of one single thread, if this line below throws exception, the next line of code will not execute. If you think your code is doing otherwise, it might be another thread doing it / some other code
in = new Scanner(new BufferedReader(new InputStreamReader(
url.openStream())));