Choosing between FileReader and InputStreamReader
Asked Answered
C

4

19

I have two methods to read Text File In java one using FileReader and Other File InputStream

FileReader fr=new FileReader("C:\\testq\\test.txt");
BufferedReader br=new BufferedReader(fr);
String s;
while((s=br.readLine())!=null){
    System.out.println("value are "+s);
}

and Other is

FileInputStream fstream = new FileInputStream("C:\\testnew\\out.text");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
while ((strLine = br.readLine()) != null){
   System.out.println (strLine);
}

Though both give me output ...I just want to know which is the best way to do it.

Chenault answered 30/3, 2012 at 7:14 Comment(1)
The DataInputStream in your second example isn't contributing anything: the code would work just the same without it.Spano
L
25

I would strongly advise using InputStreamReader instead of FileReader, but explicitly specifying the character encoding. That's really the biggest benefit of using InputStreamReader (and the lack of ability to specify an encoding for FileReader is a major hole in the API, IMO).

I'd also remove the "layer" using DataInputStream - just pass the FileInputStream to the InputStreamReader constructor.

Before Java 8

Alternatively, consider using some of the many convenience methods in Guava which can make this sort of thing much simpler. For example:

File file = new File("C:\\testnew\\out.text");
List<String> lines = Files.readLines(file, Charsets.UTF_8));

From Java 8

Java 8 introduced a bunch of new classes and methods in java.nio.files, many of which default (sensibly) to UTF-8:

Path path = Paths.get("C:\\testnew\\out.text");
List<String> lines = Files.readAllLines(path);
Limousine answered 30/3, 2012 at 7:17 Comment(17)
Thank you ..it worked but what exactly u mean by "explicitly specifying the character encoding.".. pleas can explain in little detailChenault
@Sebs_Jedi: Well which bit of it don't you understand? Currently you're calling the constructor which uses the default character encoding, but you can specify one (UTF-8, UTF-16 etc) instead. It's rarely a good idea to use the default encoding, although obviously you need to use whatever encoding the text file has been written in.Limousine
Even java.nio.file package has the same functionality with [Files.readAllLines(...)](docs.oracle.com/javase/7/docs/api/java/nio/file/…, java.nio.charset.Charset))Heterotopia
@GagandeepBali: In Java 7, yes. I'll be happy if we end up seeing more and more of Guava's functionality in the base libraries...Limousine
@Jon Skeet Hello buddy can you please give some idea of Guava.What is it or any link to start it learning ?Roentgenograph
@AndroidKiller: How about following the link in the answer? :)Limousine
@Jon Skeet If i want to use these libraries in my java project.Do i need to add edxtra jar file or something like that ?\Roentgenograph
@AndroidKiller: Yes, you add the Guava jar file.Limousine
@JonSkeet why java not allowed explicitly specifying the character encoding in FileReader too? any performance issue? can you explain?Esplanade
@UnKnown: I don't know - it's just a bad API, IMO.Limousine
@JonSkeet why bad? instead of explicitly encoding any other reason? and can you give me link where I can get clarity about where to use InputStream or Where to Use Reader`?Esplanade
@UnKnown: It's bad because you can't specify an encoding. Using the platform default encoding is almost always a bad idea. As for Reader vs InputStream - the documentation is a good start. Basically, Reader is for text, and InputStream is for binary data, as I've explained to you in another question, I'm sure...Limousine
@JonSkeet I know about text and binary data. I want to get real example like use InputStream for Socket? Networking? and Reader for files?Esplanade
@UnKnown: Sorry, this is too chatty for comments. But I'd urge you to separate "what you're reading" (text/binary) from "where you're reading it from" (network/file/whatever). They're orthogonal. This will be my last comment in this exchange.Limousine
There is no Charsets.UTF_8. It should be StandardCharsets.UTF_8.Lemmon
@Max: Charsets is in Guava - or was when this answer was written, which was before StandardCharsets existed. I can update it now, but it was correct at the time of writing.Limousine
@t.o.m.: Please stop trying to add extra code just as an edit. Just add your own answer.Limousine
S
2

Both approaches are ok because you use a BufferedReader which highly improves performance over a no-buffer approach. In your second case, there is not need to wrap the FileInputStream in a DataInputStream. The last approach, let's you specify the file encoding through the InputStreamReader which is usually an important thing.

Septemberseptembrist answered 30/3, 2012 at 7:20 Comment(0)
C
1

It depends, if you want to read a file which just contains text (i mean a text file) then you should use first case.

If you want to read some file which represents binary data (i mean image file or video file etc), you should use the second case.

Chancellery answered 30/3, 2012 at 7:21 Comment(3)
thank you for answer but can u please tell which alternative methodChenault
No, the code in the post doesn't use DataInputStream.readLine at all. It uses BufferedReader.readLine - look at it carefully.Limousine
@Sebs_Jedi you used it correctly, your code is absolutely write. I misinterprted that before. Sorry.Chancellery
C
-1

Well, you create a BufferedReader from the FileInputStream originally. You should do it as following:

FileInputStream fstream = new FileInputStream("C:\\testnew\\out.text");
BufferedInputStream bstream = new BufferedInputStream(fstream);

To get a proper stream-related approach.

Carousal answered 30/3, 2012 at 7:19 Comment(7)
Why? He wants to read text, so a reader is more appropriate - and I doubt that it's worth explicitly buffering in two layers.Limousine
I didn't mean that he should use this approach for this situation. I meant that stream related approach must be used this way :)Carousal
@AlexStybaev: So to solve a different problem, you'd use different code? I'd take that as a given... how is your answer related to the OP's actual question?Limousine
@Jon Skeet: He asked about best of two ways and I have pointed that second way is not actually right and is byte-read, not text read. Isn't it related to his question?Carousal
@AlexStybaev: The second way is using an InputStreamReader wrapped in a BufferedReader - in what way is that not right? Sure, it's wrapped in a DataInputStream unnecessarily, but that's not actually a problem. Your suggested "fix" however is only byte-oriented, despite the question clearly being about text. Did you miss the InputStreamReader by any chance?Limousine
@Jon Skeet: I've just pointed that OP's approach to wrap the stream with reader is qiute bad approach. You may treat my post as a aprroach fix, not whole problem fix.Carousal
@AlexStybaev: It's far from a bad approach - it's a good approach. The OP wants to read text - therefore he wants a Reader, not an InputStream. The right way to create a Reader from an InputStream is to use an InputStreamReader, just as is in the post. You haven't shown how you'd read text data from your BufferedInputStream...Limousine

© 2022 - 2024 — McMap. All rights reserved.