我需要使用Java逐行读取大约5-6 GB的大型文本文件。

我怎样才能快速做到呢?


当前回答

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");
}

这对我很管用。希望它也能帮助到你。

其他回答

你可以使用Scanner类

Scanner sc=new Scanner(file);
sc.nextLine();

在Java 8中,除了使用Files.lines(),还有另一种方法。如果您的输入源不是文件,而是更抽象的东西,如Reader或InputStream,则可以通过BufferedReaders lines()方法对行进行流处理。

例如:

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

BufferedReader读取的每个输入行都会调用processLine()。

我记录并测试了10种不同的Java读取文件的方法,然后让它们在测试文件中从1KB读取到1GB。下面是读取1GB测试文件的3种最快的文件读取方法。

请注意,在运行性能测试时,我没有向控制台输出任何内容,因为那会大大降低测试的速度。我只是想测试一下原始的阅读速度。

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

在Java 7,8,9中测试。总的来说,这是最快的方法。读取一个1GB的文件的时间一直都在1秒以内。

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 ()

这在Java 8和9中测试成功,但在Java 7中不能工作,因为缺少对lambda表达式的支持。读取一个1GB的文件大约需要3.5秒,这使它在读取更大的文件中排名第二。

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

测试在Java 7,8,9中工作。读取1GB的测试文件大约需要4.5秒。

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);
      }
    }
  }

你可以在这里找到所有10种文件读取方法的完整排名。

在Java 8中,你可以这样做:

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

一些注释:由Files返回的流。行(不像大多数流)需要关闭。由于这里提到的原因,我避免使用forEach()。奇怪的代码(Iterable<String>) lines::iterator将一个Stream转换为一个Iterable。

你可以使用流更精确地做到这一点:

Files.lines(Paths.get("input.txt")).forEach(s -> stringBuffer.append(s);