How to read a large text file line by line using Java?
我需要使用Java来逐行读取一个大约5-6GB的大文本文件。
我怎么能这么快?
一个常见的模式是使用
1 2 3 4 5 6 | try (BufferedReader br = new BufferedReader(new FileReader(file))) { String line; while ((line = br.readLine()) != null) { // process the line. } } |
如果假设没有字符编码,则可以更快地读取数据。例如,ASCII-7,但不会有太大的区别。很可能您对数据所做的操作将花费更长的时间。
编辑:一种不太常用的模式,可以避免
1 2 3 4 5 6 | try(BufferedReader br = new BufferedReader(new FileReader(file))) { for(String line; (line = br.readLine()) != null; ) { // process the line. } // line is not visible here. } |
更新:在Java 8中,你可以做
1 2 3 | try (Stream<String> stream = Files.lines(Paths.get(fileName))) { stream.forEach(System.out::println); } |
注意:必须将流放置在Try-with资源块中,以确保对其调用Close方法,否则在GC稍后执行此操作之前,底层文件句柄永远不会关闭。
看看这个博客:
- Java读取文件逐行-Java教程
The buffer size may be specified, or
the default size may be used. The
default is large enough for most
purposes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // 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(); |
一旦java-8退出(2014年3月),您就可以使用流:
1 2 3 | try (Stream<String> lines = Files.lines(Paths.get(filename), Charset.defaultCharset())) { lines.forEachOrdered(line -> process(line)); } |
打印文件中的所有行:
1 2 3 | try (Stream<String> lines = Files.lines(file, Charset.defaultCharset())) { lines.forEachOrdered(System.out::println); } |
这里有一个完整的错误处理和支持Java 7的字符集规范的示例。使用Java 7,可以使用"尝试资源"语法,这使得代码更干净。
如果只需要默认字符集,可以跳过输入流并使用FileReader。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | InputStream ins = null; // raw byte-stream Reader r = null; // cooked reader BufferedReader br = null; // buffered for readLine() try { String s; 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 */ } } } |
下面是groovy版本,具有完整的错误处理:
1 2 3 4 5 6 |
在Java 8中,您可以这样做:
1 2 3 4 5 6 7 | try (Stream<String> lines = Files.lines (file, StandardCharsets.UTF_8)) { for (String line : (Iterable<String>) lines::iterator) { ; } } |
一些注意事项:
你能做的就是用扫描仪扫描整个文本,然后一行一行地浏览文本。当然,您应该导入以下内容:
1 2 3 4 5 6 7 8 9 10 | 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 } } |
扫描器基本上扫描所有文本。while循环用于遍历整个文本。
旁注:.txt是文件类型文本。
FileReader不允许您指定编码,如果需要指定编码,请使用
1 2 3 4 5 6 7 8 9 10 11 12 | 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(); } |
如果您从Windows导入此文件,它可能具有ANSI编码(CP1252),因此您必须指定编码。
在Java 7中:
10我记录并测试了10种不同的方法来读取Java中的文件,然后通过使它们在1KB到1GB的测试文件中读取来运行它们。以下是读取1GB测试文件最快的3种文件读取方法。
请注意,在运行性能测试时,我没有向控制台输出任何内容,因为这会真正降低测试的速度。我只是想测试一下原始的阅读速度。
1)Java.Nio.Field.FraseByTySe()
在Java 7, 8, 9中进行测试。这是最快的方法。读取一个1GB文件的时间总是不到1秒。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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.Field.Fix.LISE()
这是在Java 8和9中成功测试的,但是由于缺少对lambda表达式的支持,它在Java 7中不起作用。在一个1GB文件中读取大约需要3.5秒,这使得它在读取较大的文件时位居第二。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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)缓冲读卡器
测试在Java 7, 8, 9中工作。读取一个1GB测试文件大约需要4.5秒。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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读取文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 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(); } } } |
您可以使用scanner类
1 2 | Scanner sc=new Scanner(file); sc.nextLine(); |
在Java 8中,还有一种使用EDCOX1(8)的替代方案。如果输入源不是文件,而是更抽象的东西,比如
例如:
1 2 3 | try (BufferedReader reader = new BufferedReader(...)) { reader.lines().foreach(line -> processLine(line)); } |
对于由
您需要在
BufferReader JavaDoc
JAVA-9:
1 2 3 | try (Stream<String> stream = Files.lines(Paths.get(fileName))) { stream.forEach(System.out::println); } |
实现这一目标的明确方法,
例如:
如果您当前目录中有
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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(); } } |
输出如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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"); } |
它对我有用。希望它也能帮助你。
我通常把阅读程序做得很简单:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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) { } } } |
您可以使用流进行更精确的操作:
1 | Files.lines(Paths.get("input.txt")).forEach(s -> stringBuffer.append(s); |
通过使用Or.ApAC.E.MuleS.IO包提供了更多的性能,特别是在使用Java 6和以下的遗留代码中。Java7有更好的API,例外更少。处理和更有用的方法
1 2 3 4 5 6 7 8 9 10 | LineIterator lineIterator =null; try{ lineIterator = FileUtils.lineIterator(new File("/home/username/m.log"),"windows-1256");//second parameter is optionanl while (lineIterator.hasNext()){ String currentLine = lineIterator.next(); //some operation } }finally { LineIterator.closeQuietly(lineIterator); } |
马文
1 2 3 4 5 6 | <!-- https://mvnrepository.com/artifact/commons-io/commons-io --> <dependency> <groupId>commons-io</groupId> commons-io</artifactId> <version>2.6</version> </dependency> |
您可以使用此代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 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(); } } } |
您也可以使用
1 2 3 4 5 6 7 | 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(); } |