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.

Raedwald
  • 46,613
  • 43
  • 151
  • 237
Basimalla Sebastin
  • 1,159
  • 3
  • 9
  • 15
  • 2
    The `DataInputStream` in your second example isn't contributing anything: the code would work just the same without it. – user207421 Mar 30 '12 at 07:21

4 Answers4

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);
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thank you ..it worked but what exactly u mean by "explicitly specifying the character encoding.".. pleas can explain in little detail – Basimalla Sebastin Mar 30 '12 at 07:22
  • @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. – Jon Skeet Mar 30 '12 at 07:25
  • Even java.nio.file package has the same functionality with [Files.readAllLines(...)](http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#readAllLines(java.nio.file.Path, java.nio.charset.Charset)) – nIcE cOw Mar 30 '12 at 07:35
  • 1
    @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... – Jon Skeet Mar 30 '12 at 07:38
  • @Jon Skeet Hello buddy can you please give some idea of Guava.What is it or any link to start it learning ? – Android Killer Mar 30 '12 at 07:42
  • @AndroidKiller: How about following the link in the answer? :) – Jon Skeet Mar 30 '12 at 07:43
  • @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 ?\ – Android Killer Mar 30 '12 at 07:45
  • @AndroidKiller: Yes, you add the Guava jar file. – Jon Skeet Mar 30 '12 at 07:51
  • @JonSkeet why java not allowed `explicitly specifying the character encoding` in `FileReader` too? any performance issue? can you explain? – Asif Mushtaq Mar 31 '16 at 06:33
  • @UnKnown: I don't know - it's just a bad API, IMO. – Jon Skeet Mar 31 '16 at 06:34
  • @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`? – Asif Mushtaq Mar 31 '16 at 06:36
  • @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... – Jon Skeet Mar 31 '16 at 06:37
  • @JonSkeet I know about text and binary data. I want to get real example like use `InputStream` for Socket? Networking? and `Reader` for files? – Asif Mushtaq Mar 31 '16 at 06:40
  • @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. – Jon Skeet Mar 31 '16 at 06:52
  • There is no Charsets.UTF_8. It should be StandardCharsets.UTF_8. – Max Barraclough Apr 28 '18 at 21:22
  • @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. – Jon Skeet Apr 29 '18 at 05:55
  • @t.o.m.: Please stop trying to add extra code just as an edit. Just add your own answer. – Jon Skeet Oct 14 '20 at 15:41
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.

Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
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.

Chandra Sekhar
  • 18,914
  • 16
  • 84
  • 125
-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.

Alex Stybaev
  • 4,623
  • 3
  • 30
  • 44
  • Why? He wants to read text, so a *reader* is more appropriate - and I doubt that it's worth explicitly buffering in *two* layers. – Jon Skeet Mar 30 '12 at 07:20
  • 1
    I didn't mean that he should use this approach for this situation. I meant that stream related approach must be used this way :) – Alex Stybaev Mar 30 '12 at 07:27
  • @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? – Jon Skeet Mar 30 '12 at 07:39
  • @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? – Alex Stybaev Mar 30 '12 at 07:41
  • @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? – Jon Skeet Mar 30 '12 at 07:44
  • @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. – Alex Stybaev Mar 30 '12 at 07:48
  • 1
    @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`... – Jon Skeet Mar 30 '12 at 07:52