998

I need to read a large text file of around 5-6 GB line by line using Java.

How can I do this quickly?

Mahozad
  • 18,032
  • 13
  • 118
  • 133
manoj singh
  • 10,045
  • 3
  • 15
  • 3
  • 94
    @kamaci et. al. This question should not be marked as a duplicate. "Quickly read the last line" is not an alternative, and its debatable whether "Quickest way to read text-file line by line" is. The quickest way to do something is not necessarily the common way. Furthermore, the answers below include code, the most relevant alternative you list does not. This question is useful. It is currently the top google search result for "java read file line by line". Finally, its off putting to arrive at stack overflow and find that 1 in every 2 question is flagged for disposal. – Patrick Cullen Feb 06 '13 at 03:47
  • 5
    [Here](http://stackoverflow.com/a/40597140/3867574) is a comparison of speed for six possible implementations. – Serg M Ten Nov 15 '16 at 09:51
  • 5
    Event though I have been reading comments arguing that SO's close policy sucks, SO persists in it. It's such a narrow minded developer perspective to want to avoid redundancy at all costs! Just let it be! The cream will rise to the top and the sh*t will sink to the bottom just fine all by itself. Even though a question may have been asked before (which question isn't??), that does not mean that a new question may not be able to phrase it better, get better answers, rank higher in search engines etc. Interestingly, this question is now 'protected'.... – Stijn de Witt Oct 03 '17 at 10:19
  • 4
    It's incredible how questions get marked as duplicate by just reading the title. – Luke Oct 25 '18 at 08:48
  • After Shog's edit this is indeed a duplicate of https://stackoverflow.com/q/5800361/103167 but this one has gotten far more activity. – Ben Voigt Jun 30 '21 at 18:51

22 Answers22

1229

A common pattern is to use

try (BufferedReader br = new BufferedReader(new FileReader(file))) {
    String line;
    while ((line = br.readLine()) != null) {
       // process the line.
    }
}

You can read the data faster if you assume there is no character encoding. e.g. ASCII-7 but it won't make much difference. It is highly likely that what you do with the data will take much longer.

EDIT: A less common pattern to use which avoids the scope of line leaking.

try(BufferedReader br = new BufferedReader(new FileReader(file))) {
    for(String line; (line = br.readLine()) != null; ) {
        // process the line.
    }
    // line is not visible here.
}

UPDATE: In Java 8 you can do

try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
        stream.forEach(System.out::println);
}

NOTE: You have to place the Stream in a try-with-resource block to ensure the #close method is called on it, otherwise the underlying file handle is never closed until GC does it much later.

Rob Kielty
  • 7,958
  • 8
  • 39
  • 51
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 6
    What does this pattern look like with proper exception handling? I note that br.close() throws IOException, which seems surprising -- what could happen when closing a file that is opened for read, anyway? FileReader's constructor might throw a FileNotFound exception. – MikeB Mar 15 '13 at 20:16
  • @MikeB In Java 7 you would add a try-with-resource block. Close is not expected to throw an exception, but some implementations might. I wouldn't expect BufferedReader is on of them. It is very rare to see developers add special handling for `close();` – Peter Lawrey Mar 16 '13 at 21:25
  • Is this the fastest Java can go? I have a ~200MB file I am reading with this method and its really slow ... is it possible to use something faster? Read in multiple lines or something? – Jiew Meng Nov 07 '13 at 09:55
  • 1
    @JiewMeng There is much faster ways to do it, however you can read 90 MB/s this way so you might save two seconds by changing the way you read it. If it is much longer than that, its not the speed of reading that is taking the time. – Peter Lawrey Nov 07 '13 at 21:38
  • 3
    If I have a 200MB file and it can read at 90MB/s then I expect it to take ~3s? Mine seem to take minutes, with this "slow" way of reading. I am on an SSD so read speeds should not be a problem? – Jiew Meng Nov 08 '13 at 00:06
  • 5
    @JiewMeng SO I would suspect something else you are doing is taking time. Can you try just reading the lines of the file and *nothing* else. – Peter Lawrey Nov 08 '13 at 00:22
  • 3
    @PeterLawrey, looks like validating the format of each line with regex is a bad idea ... I had something like `if (line.matches(regexLineFormat))` removing that sped things up alot. I still need to use `StringTokenizer` to tokenize the string. But its alot faster now thanks! – Jiew Meng Nov 08 '13 at 00:50
  • @JiewMeng You can use Scanner or your own parser possibly, but I don't use regex in any performance sensitive code. – Peter Lawrey Nov 08 '13 at 07:45
  • I always dislike this common pattern because of the while condition: `((line = br.readLine()) != null)`. This condition is *not* clear. – Stephan Dec 10 '13 at 10:42
  • 1
    @Alex in that case I wouldn't use it if you don't think it is clear. You may find the alternative is no more clear however. ;) – Peter Lawrey Dec 10 '13 at 10:44
  • 53
    Why not `for(String line = br.readLine(); line != null; line = br.readLine())` Btw, in Java 8 you can do `try( Stream lines = Files.lines(...) ){ for( String line : (Iterable) lines::iterator ) { ... } }` Which is hard not to hate. – Aleksandr Dubinsky Dec 15 '13 at 09:17
  • 33
    @AleksandrDubinsky The problem I have with closures in Java 8 is that it very easily makes the code more complicated to read (as well as being slower) I can see lots of developers overusing it because it is "cool". – Peter Lawrey Dec 15 '13 at 10:33
  • 3
    You did catch the "hate" part, right? :) Although in fact I didn't use closures/lambdas. – Aleksandr Dubinsky Dec 15 '13 at 19:13
  • 1
    @AleksandrDubinsky I am happy to use closures where they make sense. Most examples I see for closures are so trivial, it would be better, simpler to not use closures. – Peter Lawrey Dec 15 '13 at 22:42
  • 1
    @PeterLawrey Hi Peter, it'd be fun to add the new [tag:java-8] functionalities to read a file quick and clean :) – Yassin Hajaj Aug 03 '16 at 13:36
  • 2
    @YassinHajaj agreed, provided lambdas are used to make the code easier to read. They can make it harder to read if over used. We put our first major application written in Java 8 in 2014 (26,000 lines of code, much of it using Streams) and we found in some cases, using a traditional loop was cleaner when you are mutating data as you go, or producing/updating more than one collections for example. – Peter Lawrey Aug 05 '16 at 09:30
  • 1
    @YassinHajaj it's a good suggestion and I have added an example for Java 8. It's not as simple it it might appear. ;) +1 – Peter Lawrey Aug 05 '16 at 09:35
  • @PeterLawrey Yep, thanks for the edit and the info. Well I actually meant quick in the terms of writing it :) But I can trust you if you've experienced some performance issues :) – Yassin Hajaj Aug 05 '16 at 12:45
  • 1
    @YassinHajaj I meant, there is a gotcha in needing the try with resource – Peter Lawrey Aug 06 '16 at 17:13
  • @PeterLawrey, it's a good answer, but in my opinion as most voted answer by far, you should note that your solution will only work for Java 7 or later. There are still a lot of people working with Java 5 (or worst), that can't benefit from try-with-resource feature. – Albert Aug 08 '16 at 08:44
  • 1
    @Albert I assume that even those who can't write Java 7 can read Java 7 and know how to close a file when finished with it. I *wouldn't* assume people know how to read Java 8 however and retro fit stream/lambdas. ;) – Peter Lawrey Aug 08 '16 at 17:27
  • @AboozarRajabi what do you mean by "doesn't work" and what is the problem you still have? – Peter Lawrey Nov 10 '16 at 10:58
  • java.lang.OutOfMemoryError: Java heap space – Aboozar Rajabi Nov 10 '16 at 11:16
  • @AboozarRajabi if you have very long lines and very small amount of memory you may need to process just one line at a time, or a portion of a line at a time. If you run the example above do you get OOME, or is it when you process those lines? i.e. is the OOME occurring in your code of in this library? – Peter Lawrey Nov 10 '16 at 11:25
  • 1
    There're so many lines, the file is about 1 Gig, but each line is short. I get OOME when I tried to read the file using this code and just printing each of them. – Aboozar Rajabi Nov 10 '16 at 11:42
  • @AboozarRajabi in that case I would use the BufferedReader loop. – Peter Lawrey Nov 10 '16 at 11:45
  • like the below answer? – Aboozar Rajabi Nov 10 '16 at 11:46
  • @AboozarRajabi I think my answer is clearer as it uses try-with-resource. See the second line of my answer. – Peter Lawrey Nov 10 '16 at 13:41
  • Still the same problem even when I increase the Java heap size! – Aboozar Rajabi Nov 10 '16 at 14:05
  • @AboozarRajabi This is only holding one line at a time so if you have an OOME you have a really long line because that is all that is being retained. – Peter Lawrey Nov 10 '16 at 14:09
  • When I use it for shorter files (300 Mb), it's Ok but for 1.5 G file, I get OOME error. – Aboozar Rajabi Nov 10 '16 at 14:12
  • @AboozarRajabi for this to happen with BufferedReader you must be retaining data somewhere as only the line length matters otherwise. – Peter Lawrey Nov 10 '16 at 14:28
  • 1
    Be careful using the Java 8 Files.lines() method. It handles char encoding differently. The BufferedReader is lenient and will handle non-utf8 chars without fuss, but File.lines() will throw an exception if it encounters a non-utf8 char. You must specify the char encoding you expect with Files.lines() if it is not the default utf-8. – Umi Aug 09 '18 at 06:15
  • BufferedReader is from Java 1.1. How on earth did we use to read a line from a file in Java 1.0? Just feeling a bit retro. – k314159 Mar 15 '21 at 21:33
  • 1
    @k314159 Probably DataInputStream.readLine() which has been deprecated. – Peter Lawrey Mar 17 '21 at 08:41
187

Look at this blog:

The buffer size may be specified, or the default size may be used. The default is large enough for most purposes.

// Open the file
FileInputStream fstream = new FileInputStream("textfile.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));

String strLine;

//Read File Line By Line
while ((strLine = br.readLine()) != null)   {
  // Print the content on the console
  System.out.println (strLine);
}

//Close the input stream
fstream.close();
Leonardo Alves Machado
  • 2,747
  • 10
  • 38
  • 53
Naveed
  • 41,517
  • 32
  • 98
  • 131
  • 8
    My file is 1.5 Gig and it's not possible to read the file using your answer! – Aboozar Rajabi Nov 10 '16 at 12:24
  • 5
    @AboozarRajabi Of course it is possible. This code can read any text file. – user207421 May 07 '17 at 07:37
  • 12
    Downvoted for poor quality link. There is a completely pointless `DataInputStream`, and the wrong stream is closed. Nothing wrong with the Java Tutorial, and no need to cite arbitrary third-party Internet rubbish like this. – user207421 May 07 '17 at 07:41
  • 6
    I'd ditch the comments, you have 4 lines of 100% redundant comments for 6 lines of code. – Buffalo Oct 24 '19 at 08:01
131

Once Java 8 is out (March 2014) you'll be able to use streams:

try (Stream<String> lines = Files.lines(Paths.get(filename), Charset.defaultCharset())) {
  lines.forEachOrdered(line -> process(line));
}

Printing all the lines in the file:

try (Stream<String> lines = Files.lines(file, Charset.defaultCharset())) {
  lines.forEachOrdered(System.out::println);
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
msayag
  • 8,407
  • 4
  • 30
  • 29
  • 2
    Use `StandardCharsets.UTF_8`, use `Stream` for conciseness, and avoid using `forEach()` and especially `forEachOrdered()` unless there's a reason. – Aleksandr Dubinsky Dec 15 '13 at 09:29
  • 3
    Why avoid forEach()? Is it bad? – steventrouble Mar 19 '14 at 00:54
  • 1
    If I us forEach instead of forEachOrdered, the lines might be printed out of order, aren't they? – msayag Mar 20 '14 at 08:28
  • 2
    @steventrouble Take a look at: http://stackoverflow.com/questions/16635398/java-8-iterable-foreach-vs-foreach-loop It's not bad if you pass a short function reference like `forEach(this::process)`, but it gets ugly if you write blocks of code as lambdas inside `forEach()`. – Aleksandr Dubinsky Mar 08 '15 at 14:54
  • 2
    @msayag, You're right, you need `forEachOrdered` in order to execute in-order. Be aware that you won't be able to parallelize the stream in that case, although I've found that parallelization doesn't turn on unless the file has thousands of lines. – Aleksandr Dubinsky Mar 08 '15 at 15:02
  • `file` is misleading in `Files.lines(file, Charset.defaultCharset())`. I like `file.toPath()` or `path`. – SedJ601 Sep 11 '20 at 16:02
41

Here is a sample with full error handling and supporting charset specification for pre-Java 7. With Java 7 you can use try-with-resources syntax, which makes the code cleaner.

If you just want the default charset you can skip the InputStream and use FileReader.

InputStream ins = null; // raw byte-stream
Reader r = null; // cooked reader
BufferedReader br = null; // buffered for readLine()
try {
    String s;
    if (true) {
        String data = "#foobar\t1234\n#xyz\t5678\none\ttwo\n";
        ins = new ByteArrayInputStream(data.getBytes());
    } else {
        ins = new FileInputStream("textfile.txt");
    }
    r = new InputStreamReader(ins, "UTF-8"); // leave charset out for default
    br = new BufferedReader(r);
    while ((s = br.readLine()) != null) {
        System.out.println(s);
    }
}
catch (Exception e)
{
    System.err.println(e.getMessage()); // handle exception
}
finally {
    if (br != null) { try { br.close(); } catch(Throwable t) { /* ensure close happens */ } }
    if (r != null) { try { r.close(); } catch(Throwable t) { /* ensure close happens */ } }
    if (ins != null) { try { ins.close(); } catch(Throwable t) { /* ensure close happens */ } }
}

Here is the Groovy version, with full error handling:

File f = new File("textfile.txt");
f.withReader("UTF-8") { br ->
    br.eachLine { line ->
        println line;
    }
}
user207421
  • 305,947
  • 44
  • 307
  • 483
DarkStar
  • 555
  • 4
  • 5
  • 1
    What does a `ByteArrayInputStream` fed by a string literal have to do with reading a large text file? – user207421 May 07 '17 at 07:42
  • 1
    absolutely useless closes. There is zero reason to close every stream. If you close any of those streams you automatically close all other streams... – Enerccio Jun 19 '19 at 09:33
28

I documented and tested 10 different ways to read a file in Java and then ran them against each other by making them read in test files from 1KB to 1GB. Here are the fastest 3 file reading methods for reading a 1GB test file.

Note that when running the performance tests I didn't output anything to the console since that would really slow down the test. I just wanted to test the raw reading speed.

1) java.nio.file.Files.readAllBytes()

Tested in Java 7, 8, 9. This was overall the fastest method. Reading a 1GB file was consistently just under 1 second.

import java.io..File;
import java.io.IOException;
import java.nio.file.Files;

public class ReadFile_Files_ReadAllBytes {
  public static void main(String [] pArgs) throws IOException {
    String fileName = "c:\\temp\\sample-1GB.txt";
    File file = new File(fileName);

    byte [] fileBytes = Files.readAllBytes(file.toPath());
    char singleChar;
    for(byte b : fileBytes) {
      singleChar = (char) b;
      System.out.print(singleChar);
    }
  }
}

2) java.nio.file.Files.lines()

This was tested successfully in Java 8 and 9 but it won't work in Java 7 because of the lack of support for lambda expressions. It took about 3.5 seconds to read in a 1GB file which put it in second place as far as reading larger files.

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.stream.Stream;

public class ReadFile_Files_Lines {
  public static void main(String[] pArgs) throws IOException {
    String fileName = "c:\\temp\\sample-1GB.txt";
    File file = new File(fileName);

    try (Stream linesStream = Files.lines(file.toPath())) {
      linesStream.forEach(line -> {
        System.out.println(line);
      });
    }
  }
}

3) BufferedReader

Tested to work in Java 7, 8, 9. This took about 4.5 seconds to read in a 1GB test file.

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class ReadFile_BufferedReader_ReadLine {
  public static void main(String [] args) throws IOException {
    String fileName = "c:\\temp\\sample-1GB.txt";
    FileReader fileReader = new FileReader(fileName);

    try (BufferedReader bufferedReader = new BufferedReader(fileReader)) {
      String line;
      while((line = bufferedReader.readLine()) != null) {
        System.out.println(line);
      }
    }
  }

You can find the complete rankings for all 10 file reading methods here.

gomisha
  • 2,587
  • 3
  • 25
  • 33
  • 2
    Your guide is amazing :) – Faisal Julaidan May 22 '18 at 19:35
  • 2
    You are mostly timing `System.out.print/println()` here; you are also assuming the file will fit into memory in your first two cases. – user207421 Sep 12 '19 at 07:41
  • Fair enough. Maybe I could've made those assumptions more explicit in my answer. – gomisha Sep 12 '19 at 17:06
  • 3
    the question asked for reading line by line, only last method qualifies... – eis Oct 28 '20 at 06:26
  • @eis Given that he tested 10 ways to read a file and the third fastest is line-by-line, it can be assumed reasonably that the third method shown here is also the fastest way to read a file line-by-line. I would argue then that he not only fully answered the question, but gave additional information as well which is quite useful to know. – Blue Dev Jul 19 '22 at 13:47
21

What you can do is scan the entire text using Scanner and go through the text line by line. Of course you should import the following:

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public static void readText throws FileNotFoundException {
    Scanner scan = new Scanner(new File("samplefilename.txt"));
    while(scan.hasNextLine()){
        String line = scan.nextLine();
        //Here you can manipulate the string the way you want
    }
}

Scanner basically scans all the text. The while loop is used to traverse through the entire text.

The .hasNextLine() function is a boolean that returns true if there are still more lines in the text. The .nextLine() function gives you an entire line as a String which you can then use the way you want. Try System.out.println(line) to print the text.

Side Note: .txt is the file type text.

guido
  • 18,864
  • 6
  • 70
  • 95
iskandarchacra
  • 358
  • 3
  • 7
  • Shouldn't the method declaration look instead of this: ´public static void readText throws FileNotFoundException(){´ Like: ´public static void readText() throws FileNotFoundException{´ – Ketcomp Jan 26 '16 at 16:13
  • This is considerably slower than `BufferedReader.readLine()`, and he asked for the best-performing method. – user207421 May 07 '17 at 07:43
20

In Java 8, you could do:

try (Stream<String> lines = Files.lines (file, StandardCharsets.UTF_8))
{
    for (String line : (Iterable<String>) lines::iterator)
    {
        ;
    }
}

Some notes: The stream returned by Files.lines (unlike most streams) needs to be closed. For the reasons mentioned here I avoid using forEach(). The strange code (Iterable<String>) lines::iterator casts a Stream to an Iterable.

Community
  • 1
  • 1
Aleksandr Dubinsky
  • 22,436
  • 15
  • 82
  • 99
  • By not implementing `Iterable` this code is definitively **ugly** although useful. It needs a cast (ie `(Iterable)`) to work. – Stephan Dec 15 '13 at 12:24
  • How can I skip the first line with this method? – qed Nov 05 '14 at 21:05
  • 2
    @qed `for(String line : (Iterable) lines.skip(1)::iterator)` – Aleksandr Dubinsky Nov 12 '14 at 00:48
  • 1
    If you’re not intending to actually use `Stream` features, using `Files.newBufferedReader` instead of `Files.lines` and repeatedly calling `readLine()` until `null` instead of using constructs like `(Iterable) lines::iterator` seems to be much simpler… – Holger Jul 28 '17 at 11:14
  • Why do you use :: in lines::iterator? Only usage I know for :: is to package method name into lambda function. In for loop parameter after : should be variable while you get some lambda method using :: – Trismegistos Oct 04 '17 at 11:09
  • @Trismegistos the code indeed creates a lambda. The lambda is then cast into an `Iterable` (this is possible because `Iterable` is a functional interface). The for loop then iterates over this new object. All this is necessary because interface `Stream` does not inherit from `Iterable` despite satisfying its contract. – Aleksandr Dubinsky Oct 05 '17 at 10:42
  • 1
    @user207421 Why do you say it reads the file into memory? The javadoc says, `Unlike readAllLines, [File.lines] does not read all lines into a List, but instead populates lazily as the stream is consumed... The returned stream encapsulates a Reader.` – Aleksandr Dubinsky Sep 23 '19 at 13:16
18

FileReader won't let you specify the encoding, use InputStreamReaderinstead if you need to specify it:

try {
    BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "Cp1252"));         

    String line;
    while ((line = br.readLine()) != null) {
        // process the line.
    }
    br.close();

} catch (IOException e) {
    e.printStackTrace();
}

If you imported this file from Windows, it might have ANSI encoding (Cp1252), so you have to specify the encoding.

ישו אוהב אותך
  • 28,609
  • 11
  • 78
  • 96
live-love
  • 48,840
  • 22
  • 240
  • 204
16

In Java 7:

String folderPath = "C:/folderOfMyFile";
Path path = Paths.get(folderPath, "myFileName.csv"); //or any text file eg.: txt, bat, etc
Charset charset = Charset.forName("UTF-8");

try (BufferedReader reader = Files.newBufferedReader(path , charset)) {
  while ((line = reader.readLine()) != null ) {
    //separate all csv fields into string array
    String[] lineVariables = line.split(","); 
  }
} catch (IOException e) {
    System.err.println(e);
}
Diego Duarte
  • 477
  • 5
  • 8
  • 9
    be aware! using line.split this way will NOT parse properly if a field contains a comma and it is surrounded by quotes. This split will ignore that and just separate the field in chunks using the internal comma. HTH, Marcelo. – Marcelo Finki Oct 13 '14 at 15:23
  • CSV: Comma Separated Values file, thus you shouldn't use comma in a csv field, unless you mean to add another field. So, use split for comma token in java when parsing a CSV file is perfectly fine and right – Diego Duarte Feb 19 '15 at 14:33
  • 7
    Diego, this is not correct. The only CSV standard (RFC 4180) specifically says "Fields containing line breaks (CRLF), double quotes, and commas should be enclosed in double-quotes." – serg.nechaev Feb 27 '15 at 02:06
  • 2
    Use `StandardCharsets.UTF_8` to avoid the checked exception in `Charset.forName("UTF-8")` – Aleksandr Dubinsky Mar 08 '15 at 15:20
  • 2
    Thank you "Diego Duarte" for your comment; i must say i agree with what "serg.nechaev" replies. I see commas embedded in csv files 'all the time'. People expect that this will be accepted. with all due respect. also a big thanks to "serg.nechaev". IMHO you are right. Cheerse Everyone. – Marcelo Finki Mar 13 '15 at 15:09
15

In Java 8, there is also an alternative to using Files.lines(). If your input source isn't a file but something more abstract like a Reader or an InputStream, you can stream the lines via the BufferedReaders lines() method.

For example:

try (BufferedReader reader = new BufferedReader(...)) {
  reader.lines().forEach(line -> processLine(line));
}

will call processLine() for each input line read by the BufferedReader.

djna
  • 54,992
  • 14
  • 74
  • 117
Rüdiger Herrmann
  • 20,512
  • 11
  • 62
  • 79
13

For reading a file with Java 8

package com.java.java8;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;

/**
 * The Class ReadLargeFile.
 *
 * @author Ankit Sood Apr 20, 2017
 */
public class ReadLargeFile {

    /**
     * The main method.
     *
     * @param args
     *            the arguments
     */
    public static void main(String[] args) {
        try {
            Stream<String> stream = Files.lines(Paths.get("C:\\Users\\System\\Desktop\\demoData.txt"));
            stream.forEach(System.out::println);
        }
        catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ankit Sood
  • 257
  • 3
  • 5
10

You can use Scanner class

Scanner sc=new Scanner(file);
sc.nextLine();
Abhilash
  • 458
  • 2
  • 7
  • 2
    @Tim 'Bomb horribly' is not a term I recognize in CS. What exactly do you mean? – user207421 Nov 17 '13 at 20:50
  • Bog down, execute very slowly, most likely crash. I probably should avoid idioms on this site ;) – Tim Nov 18 '13 at 14:52
  • 4
    @Tim Why would it do so? – xehpuk Feb 22 '15 at 19:18
  • 2
    Using `Scanner` is fine, but this answer does not include the full code to use it properly. – Aleksandr Dubinsky Mar 08 '15 at 14:58
  • 5
    @Tim This code will neither 'bomb horribly' nor 'bog down' nor 'execute very slowly' nor 'most likely crash'. As a matter of fact as written it will only read one line, almost instaneously. You can read megabytes per second this way, although `BufferedReader.readLine()` is certainly several times as fast. If you think otherwise please provide your reasons. – user207421 Aug 03 '15 at 04:52
8

Java 9:

try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
    stream.forEach(System.out::println);
}
Community
  • 1
  • 1
Abdennour TOUMI
  • 87,526
  • 38
  • 249
  • 254
7

You need to use the readLine() method in class BufferedReader. Create a new object from that class and operate this method on him and save it to a string.

BufferReader Javadoc

user207421
  • 305,947
  • 44
  • 307
  • 483
Master C
  • 1,536
  • 4
  • 14
  • 19
6

The clear way to achieve this,

For example:

If you have dataFile.txt on your current directory

import java.io.*;
import java.util.Scanner;
import java.io.FileNotFoundException;

public class readByLine
{
    public readByLine() throws FileNotFoundException
    {
        Scanner linReader = new Scanner(new File("dataFile.txt"));

        while (linReader.hasNext())
        {
            String line = linReader.nextLine();
            System.out.println(line);
        }
        linReader.close();

    }

    public static void main(String args[])  throws FileNotFoundException
    {
        new readByLine();
    }
}

The output like as below, enter image description here

Rajamohan S
  • 7,229
  • 5
  • 36
  • 54
  • Why is it clearer? And don't post pictures of text here. Post the text. – user207421 Oct 28 '16 at 02:49
  • You posted a picture. It is a picture of text. You could have cut and pasted the text directly into this page. Nobody said anything about posting programs. Posting pictures of text is a waste of your time, which I don't care about, and oyur bandwidth, which I do. – user207421 May 07 '17 at 07:46
3
BufferedReader br;
FileInputStream fin;
try {
    fin = new FileInputStream(fileName);
    br = new BufferedReader(new InputStreamReader(fin));

    /*Path pathToFile = Paths.get(fileName);
    br = Files.newBufferedReader(pathToFile,StandardCharsets.US_ASCII);*/

    String line = br.readLine();
    while (line != null) {
        String[] attributes = line.split(",");
        Movie movie = createMovie(attributes);
        movies.add(movie);
        line = br.readLine();
    }
    fin.close();
    br.close();
} catch (FileNotFoundException e) {
    System.out.println("Your Message");
} catch (IOException e) {
    System.out.println("Your Message");
}

It works for me. Hope It will help you too.

YakovL
  • 7,557
  • 12
  • 62
  • 102
Dipendra Ghatal
  • 121
  • 1
  • 7
3

You can use streams to do it more precisely:

Files.lines(Paths.get("input.txt")).forEach(s -> stringBuffer.append(s);
Kirill
  • 7,580
  • 6
  • 44
  • 95
spidy
  • 65
  • 4
  • 2
    I agree that it is actually fine. Aguess, people dislike it because of strange StringBuffer choice (StringBuilder is generally preferred, even though it might just be a bad name for variable). Also because it is already mentioned above. – Andrii Rubtsov Apr 20 '18 at 11:20
2

I usually do the reading routine straightforward:

void readResource(InputStream source) throws IOException {
    BufferedReader stream = null;
    try {
        stream = new BufferedReader(new InputStreamReader(source));
        while (true) {
            String line = stream.readLine();
            if(line == null) {
                break;
            }
            //process line
            System.out.println(line)
        }
    } finally {
        closeQuiet(stream);
    }
}

static void closeQuiet(Closeable closeable) {
    if (closeable != null) {
        try {
            closeable.close();
        } catch (IOException ignore) {
        }
    }
}
Binkan Salaryman
  • 3,008
  • 1
  • 17
  • 29
1

By using the org.apache.commons.io package, it gave more performance, especially in legacy code which uses Java 6 and below.

Java 7 has a better API with fewer exceptions handling and more useful methods:

LineIterator lineIterator = null;
try {
    lineIterator = FileUtils.lineIterator(new File("/home/username/m.log"), "windows-1256"); // The second parameter is optionnal
    while (lineIterator.hasNext()) {
        String currentLine = lineIterator.next();
        // Some operation
    }
}
finally {
    LineIterator.closeQuietly(lineIterator);
}

Maven

<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
mohsen.nour
  • 1,089
  • 3
  • 20
  • 27
-1

You can also use Apache Commons IO:

File file = new File("/home/user/file.txt");
try {
    List<String> lines = FileUtils.readLines(file);
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
To Kra
  • 3,344
  • 3
  • 38
  • 45
  • 6
    `FileUtils.readLines(file)` is a deprecated method. Additionally, the method invokes [`IOUtils.readLines`](http://grepcode.com/file/repo1.maven.org/maven2/commons-io/commons-io/1.4/org/apache/commons/io/IOUtils.java#IOUtils.readLines%28java.io.Reader%29), which uses a BufferedReader and ArrayList. This is not a line-by-line method, and certainly not one that would be practical for reading several GB. – Parker Jun 21 '15 at 22:52
-1

You can use this code:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class ReadTextFile {

    public static void main(String[] args) throws IOException {

        try {

            File f = new File("src/com/data.txt");

            BufferedReader b = new BufferedReader(new FileReader(f));

            String readLine = "";

            System.out.println("Reading file using Buffered Reader");

            while ((readLine = b.readLine()) != null) {
                System.out.println(readLine);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}
Usman Yaqoob
  • 535
  • 5
  • 13
-2

For Android developers ending up here (who use Kotlin):

val myFileUrl = object{}.javaClass.getResource("/vegetables.txt")
val file = File(myFileUrl.toURI())
file
    .bufferedReader()
    .lineSequence()
    .forEach(::println)

Or:

val myFileUrl = object{}.javaClass.getResource("/vegetables.txt")
val file = File(myFileUrl.toURI())
file.useLines { lines ->
    lines.forEach(::println)
}

Notes:

  • The vegetables.txt file should be in your classpath (for example, in src/main/resources directory)

  • The above solutions all treat the file encodings as UTF-8 by default. You can specify your desired encoding as the argument for the functions.

  • The above solutions do not need any further action like closing the files or readers. They are automatically taken care of by the Kotlin standard library.

Mahozad
  • 18,032
  • 13
  • 118
  • 133