BufferedReaders reading System.in across classes - java

I was wondering why I get a java.io.IOException: Stream closederror when using
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
In 2 different classes.
The setup is as follows.
public class SomeClass{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//br.readSomeStuff
br.close();
new SomeOtherClass(); //defo not passing the br along to the new class!
}
public class SomeOtherClass{
public SomeOtherClass(){
method():
}
private void method(){
BufferedReader br = new BufferedReader(new InputStreamReader(System.in))
br.readLine();
// results into an IOEXCEPTION Stream close
}
}
The issue is gone when I close the BufferedReader in the first class AFTER the creation of the other class. I dont understand why this would give issues though. I am creating a new BufferedReader on System.in, why could this possibly result into a stream closed error?
Similar question here. Does not explain WHY System.in is closed for some reason though.
Thanks in advance!

Because when you close the BufferedReader all the underlying streams are closed. THis is the case with all the classes that wrap and read/write from/to streams.
This is a convenience so that you don't need to go through the entire set of objects you've instantiated (the InputStream, the InputStreamReader and finally the BufferedReader) and close all of them.
A simple test will demonstrate this:
public static void main(String[] args) throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
br.close();
// Will throw IOException
int i = System.in.read();
}
System.in isn't special; it's an InputStream. The same thing would happen if the underlying stream was say, a FileInputStream rather than stdin:
public static void main(String[] args) throws IOException
{
File f = new File("SomeFileName");
FileInputStream fis = new FileInputStream(f);
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
br.close();
// throw IOException
int i = fis.read();
}
Given that usually these constructors are chained (as they are in your example), it would be annoyingly cumbersome to have to retain and close each one.
Imagine having to do the following every time you wanted to use streams:
public static void main(String[] args) throws IOException
{
File f = new File("SomeFileName");
FileInputStream fis = new FileInputStream(f);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(irs);
// Use the BufferedReader
br.close();
isr.close();
fis.close();
}

Related

how to recover BufferedReader object from ByeArrayOutputStream

I have written a code to stub the System.out.println and passing the object of BuffredReader into it.
My question is how to recover the BufferedReader object?
import java.io.*;
class Test {
public static void main(String args[]) throws IOException {
// stubbing the default print statement
ByteArrayOutputStream outcontent = new ByteArrayOutputStream();
System.setOut(new PrintStream(outcontent);
//createing a BufferedReader obj and passing to print
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println(br);
//trying to get the value from the outcontent and
// but i need to serialise this to BufferedReader
System.err.println(outContent.toString());
}
}
I have tried to use this answer but i am getting the error java.io.StreamCorruptedException: invalid stream header: 6A617661
Since you already have a ByteArrayOutputStream, you should try something like this:
BufferedReader reader = new BuffererdBeader( new InputStreamReader(
new ByteArrayInputStream( outcontent.toByteArray() ) ) );

Java: Unable to read file using FileReader [duplicate]

I'm trying to read input from a file to be taken into a Java applet to be displayed as a Pac-man level, but I need to use something similar to getLine()... So I searched for something similar, and this is the code I found:
File inFile = new File("textfile.txt");
FileInputStream fstream = new FileInputStream(inFile);//ERROR
// Get the object of DataInputStream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
The line I marked "ERROR" gives me an error that says "Default constructor cannot handle exception type FileNotFoundException thrown by implicit super constructor. Must define an explicit constructor."
I've searched for this error message, but everything I find seems to be unrelated to my situation.
Either declare a explicit constructor at your subclass that throws FileNotFoundException:
public MySubClass() throws FileNotFoundException {
}
Or surround the code in your base class with a try-catch block instead of throwing a FileNotFoundException exception:
public MyBaseClass() {
FileInputStream fstream = null;
try {
File inFile = new File("textfile.txt");
fstream = new FileInputStream(inFile);
// Get the object of DataInputStream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
// Do something with the stream
} catch (FileNotFoundException ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
} finally {
try {
// If you don't need the stream open after the constructor
// else, remove that block but don't forget to close the
// stream after you are done with it
fstream.close();
} catch (IOException ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
}
}
}
Unrelated, but since you are coding a Java applet, remember that you will need to sign it in order to perform IO operations.
You need to surround your code with try and catch as follows:
try {
File inFile = new File("textfile.txt");
FileInputStream fstream = new FileInputStream(inFile);//ERROR
} catch (FileNotFoundException fe){
fe.printStackTrace();
}
// Get the object of DataInputStream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
This is guesswork as we don't have the complete code.
From the Javadoc:
public FileInputStream(File file) throws FileNotFoundException
It means that when you do a new FileInputStream() like you do, it can come back with a FileNotFoundException. This is a checked exception, that you need to either rethrow (i.e. add 'throws FileNotFoundException' in the method where you do the new) or catch (see other try/catch responses).

Java - how to read from file when I used PrintWriter, BufferedWriter and FileWriter to write?

I have method which writes some data to file. I use PrintWriter, BufferedWriter and FileWriter as shown below
public void writeToFile(String FileName){
PrintWriter pw = null;
try {
pw = new PrintWriter(new BufferedWriter(new FileWriter(FileName)));
for(Cars car : list){
pw.println(car.getType());
pw.println(car.getMaxSpeed());
pw.println(car.getOwner());
pw.println();
pw.flush();
}
pw.close();
}
catch(IOException ex){
System.err.println(ex);
}
}
Now how can I read this data from file? I tried to use InputStreamReader, BufferedReader and FileInputStream, but my NetBeans shows me an error message
public void readFromFile() throws IOException {
InputStreamReader fr = null;
try {
fr = new InputStreamReader(new BufferedReader(new FileInputStream(new FileReader("c:\\cars.txt"))));
System.out.println(fr.read());
} catch (Exception ex) {
System.out.println(ex.getMessage());
} finally {
fr.close();
}
}
What is wrong with this method?
BufferedReader in = new BufferedReader(new FileReader("file.in"));
BufferedWriter out = new BufferedWriter(new FileWriter("file.out"));
String line = in.readLine(); // <-- read whole line
StringTokenizer tk = new StringTokenizer(line);
int a = Integer.parseInt(tk.nextToken()); // <-- read single word on line and parse to int
out.write(""+a);
out.flush();
There are several problems in your code :
1) An InputStreamReader takes an InputStream as an argument not a Reader. See http://docs.oracle.com/javase/6/docs/api/java/io/InputStreamReader.html.
2) The FileInputStream does not accept a Reader as argument as well (it takes a File, a FileDescriptor, or a String). See : http://docs.oracle.com/javase/6/docs/api/java/io/FileInputStream.html
3) A BufferedReader reads the File line by line normally. The read() method only reads a single character.
A possible solution could be :
fr = new BufferedReader(new InputStreamReader(new FileInputStream(new File("c:\\cars.txt"))));
String line = "";
while((line = fr.readLine()) != null) {
System.out.println(line);
}
Btw : It would be easier for others to help you, if you provide the exact error-message or even better the StackTrace.
Simple error: Cannot resolve constructor 'FileInputStream(java.io.FileReader)', required constructor not exist in API.
Your original code was:
new PrintWriter(new BufferedWriter(new FileWriter(FileName)));
so for reading, you need
new PrintReader(new BufferedReader(new FileReader(FileName)));
but PrintReader is not needed (not exist), so all you need is:
new BufferedReader(new FileReader(FileName))
PrinterWriter prints formatted representations of objects to a text-output stream, but when reading text is always formatted, so PrinterReader not exist.
You are writing line by line, so also read line by line :) Example:
public void readFromFile() throws IOException {
BufferedReader bufferedReader = null;
try {
String sCurrentLine;
bufferedReader = new BufferedReader(new FileReader("c:\\cars.txt"));
while ((sCurrentLine = bufferedReader.readLine()) != null) {
System.out.println(sCurrentLine);
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
} finally {
bufferedReader.close();
}
}
or better (JDK7)
void readFromFile() throws IOException {
Path path = Paths.get("c:\\cars.txt");
try (BufferedReader reader = Files.newBufferedReader(path, Charset.defaultCharset())){
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
}

Good practice in Java File I/O

I am trying to read integers from a file, apply some operation on them and writing those resulting integers to another file.
// Input
FileReader fr = new FileReader("test.txt");
BufferedReader br = new BufferedReader(fr);
Scanner s = new Scanner(br);
// Output
FileWriter fw = new FileWriter("out.txt");
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter pw = new PrintWriter(bw);
int i;
while(s.hasNextInt())
{
i = s.nextInt();
pw.println(i+5);
}
I want to ask is it a good practice to wrap these input and output streams like this?
I am new to java and on internet, I saw lots of other ways of I/O in files. I want to stick to one approach so is above the best approach ?
- Well consider that you went shopping into a food mall, Now what you do usually, pick-up each item from the selves and then go to the billing counter then again go to the selves and back to billing counter ....?? Or Store all the item into a Cart then go to the billing counter.
- Its similar here in Java, Files deal with bytes, and Buffer deals with characters, so there is a conversion of bytes to characters and trust me it works well, there will not be any noticeable overhead.
So to Read the File:
File f = new File("Path");
FileReader fr = new FileReader(f);
BufferedReader br = new BufferedReader(fr);
So to Write the File:
File f = new File("Path");
FileWriter fw = new FileWriter(f);
BufferedWriter bw = new BufferedWriter(fw);
And when you use Scanner there is no need to use BufferedReader
Keep in mind that the design of those classes is based on the Decorator design pattern. A good practice is to close all instances of java.io.Closeable in a finally block. For example:
Reader r = null;
Scanner s = null;
try {
r = new FileReader("test.txt");
s = new Scanner(r);
// Do your stuff here.
} finally {
if (r != null)
r.close();
if (s != null)
s.close();
}
or, if you are using Java 7 or higher:
try (
Reader r = new FileReader("test.txt");
Scanner s = new Scanner(r)
) {
// Do your stuff here.
}
you dont really need BuffredWriter when you are using PrintWriter to write character data, printwriter has a constructor which takes filewriter as an argument. and dont need a scanner to read from a file you could acheive it using bufferedreader itself.
FileReader fr = new FileReader("test.txt");
BufferedReader br = new BufferedReader(fr);
while((line=br.readLine())!=null){
//do read operations here
}
FileWriter fw = new FileWriter("out.txt");
PrintWriter pw = new PrintWriter(fw);
pw.println("write some data to the file")
Scanner does not need the BufferedReader. You can wrap it over the FileReader.
Scanner s = new Scanner(new FileReader("test.txt"));
While using the scanner its better to assume that the source contains various content. Its good to close the scanner after using it.
while(s.hasNext()){
if(s.hasNextInt())
int i = s.nextInt();
s.next();
}
s.close();
I usually do this:
String inputFileLocation = "Write it here";
BufferedReader br = new BufferedReader(new FileReader(new File(fileLocation)));
while((line=br.readLine())!=null){
//Scanner operations here
}
String outputFileLocation = "Here";
PrintWriter pr = new PrintWriter(new FileWriter(new File(outputFileLocation)));

GZIPInputStream reading line by line

I have a file in .gz format. The java class for reading this file is GZIPInputStream.
However, this class doesn't extend the BufferedReader class of java. As a result, I am not able to read the file line by line. I need something like this
reader = new MyGZInputStream( some constructor of GZInputStream)
reader.readLine()...
I though of creating my class which extends the Reader or BufferedReader class of java and use GZIPInputStream as one of its variable.
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Reader;
import java.util.zip.GZIPInputStream;
public class MyGZFilReader extends Reader {
private GZIPInputStream gzipInputStream = null;
char[] buf = new char[1024];
#Override
public void close() throws IOException {
gzipInputStream.close();
}
public MyGZFilReader(String filename)
throws FileNotFoundException, IOException {
gzipInputStream = new GZIPInputStream(new FileInputStream(filename));
}
#Override
public int read(char[] cbuf, int off, int len) throws IOException {
// TODO Auto-generated method stub
return gzipInputStream.read((byte[])buf, off, len);
}
}
But, this doesn't work when I use
BufferedReader in = new BufferedReader(
new MyGZFilReader("F:/gawiki-20090614-stub-meta-history.xml.gz"));
System.out.println(in.readLine());
Can someone advice how to proceed ..
The basic setup of decorators is like this:
InputStream fileStream = new FileInputStream(filename);
InputStream gzipStream = new GZIPInputStream(fileStream);
Reader decoder = new InputStreamReader(gzipStream, encoding);
BufferedReader buffered = new BufferedReader(decoder);
The key issue in this snippet is the value of encoding. This is the character encoding of the text in the file. Is it "US-ASCII", "UTF-8", "SHIFT-JIS", "ISO-8859-9", …? there are hundreds of possibilities, and the correct choice usually cannot be determined from the file itself. It must be specified through some out-of-band channel.
For example, maybe it's the platform default. In a networked environment, however, this is extremely fragile. The machine that wrote the file might sit in the neighboring cubicle, but have a different default file encoding.
Most network protocols use a header or other metadata to explicitly note the character encoding.
In this case, it appears from the file extension that the content is XML. XML includes the "encoding" attribute in the XML declaration for this purpose. Furthermore, XML should really be processed with an XML parser, not as text. Reading XML line-by-line seems like a fragile, special case.
Failing to explicitly specify the encoding is against the second commandment. Use the default encoding at your peril!
GZIPInputStream gzip = new GZIPInputStream(new FileInputStream("F:/gawiki-20090614-stub-meta-history.xml.gz"));
BufferedReader br = new BufferedReader(new InputStreamReader(gzip));
br.readLine();
BufferedReader in = new BufferedReader(new InputStreamReader(
new GZIPInputStream(new FileInputStream("F:/gawiki-20090614-stub-meta-history.xml.gz"))));
String content;
while ((content = in.readLine()) != null)
System.out.println(content);
You can use the following method in a util class, and use it whenever necessary...
public static List<String> readLinesFromGZ(String filePath) {
List<String> lines = new ArrayList<>();
File file = new File(filePath);
try (GZIPInputStream gzip = new GZIPInputStream(new FileInputStream(file));
BufferedReader br = new BufferedReader(new InputStreamReader(gzip));) {
String line = null;
while ((line = br.readLine()) != null) {
lines.add(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace(System.err);
} catch (IOException e) {
e.printStackTrace(System.err);
}
return lines;
}
here is with one line
try (BufferedReader br = new BufferedReader(
new InputStreamReader(
new GZIPInputStream(
new FileInputStream(
"F:/gawiki-20090614-stub-meta-history.xml.gz")))))
{br.readLine();}

Categories