如何在Java中逐行读取文件
本文翻译自How to read a file line by line in Javahtml
有时咱们想逐行读取一个文件来处理内容。 一个很好的例子是逐行读取CSV文件,而后将其用逗号(,)分红多列。java
在Java中,当您须要逐行读取文件时,有多种选项可供选择。git
1.Scanner
Scanner
类提供了用Java逐行读取文件的最简单方法。 咱们可使用Scanner类打开文件,而后逐行读取其内容。github
Scanner程序使用定界符模式将其输入分为令牌,在本例中为新行:web
try { // open file to read Scanner scanner = new Scanner(new File("examplefile.txt")); // read until end of file (EOF) while (scanner.hasNextLine()) { System.out.println(scanner.nextLine()); } // close the scanner scanner.close(); } catch (FileNotFoundException ex) { ex.printStackTrace(); }
若是此扫描程序的输入中有另外一行而不推动文件读取位置,则hasNextLine()
方法将返回true
。shell
要读取数据并移至下一行,咱们应使用nextLine()
方法。 此方法将扫描仪移到当前行以后,并返回当前行的其他部分,但不包括最后的任何行分隔符。 而后将读取位置设置为下一行的开头。api
因为nextLine()
方法继续在输入中搜索以寻找行分隔符,所以若是不存在行分隔符,它能够缓冲全部要搜索的输入以跳过该行。数组
2. BufferedReader
BufferedReader类提供了一种从字符输入流中读取字符,数组和行的有效方法。oracle
顾名思义,它最多可缓冲8MB(或8192KB)的字符,对于大多数用例而言,这足够大。 若是您正在读取的文件大于默认缓冲区大小,则能够自定义默认大小:dom
BufferedReader br = new BufferedReader(new FileReader(" foo.txt"), size);
BufferedReader
构造函数接受一个Reader
实例(如FileReader
,InputStreamReader
)做为字符输入流源。 这是一个简单的示例,显示了如何使用它逐行读取文件:
try { // create a reader instance BufferedReader br = new BufferedReader(new FileReader("examplefile.txt")); // read until end of file String line; while ((line = br.readLine()) != null) { System.out.println(line); } // close the reader br.close(); } catch (IOException ex) { ex.printStackTrace(); }
readLine()
方法从文件中读取一行文本,并返回一个包含该行内容的字符串,但不包括任何行终止字符或null。
注意
:null值并不表示字符串为空。 而是代表已到达文件末尾。
另外,您可使用BufferedReader
类中的lines()
方法返回行流。 您能够轻松地将此流转换为列表或阅读如下内容:
try { // create a reader instance BufferedReader br = new BufferedReader(new FileReader("examplefile.txt")); // list of lines List<String> list = new ArrayList<>(); // convert stream into list list = br.lines().collect(Collectors.toList()); // print all lines list.forEach(System.out::println); // close the reader br.close(); } catch (IOException ex) { ex.printStackTrace(); }
3. Java 8 Stream
Java 8 Stream是另外一种逐行读取文件的方式(尽管更干净)。 咱们可使用Files.lines()
静态方法来初始化行流,以下所示:
try { // initialize lines stream Stream<String> stream = Files.lines(Paths.get("examplefile.txt")); // read lines stream.forEach(System.out::println); // close the stream stream.close(); } catch (IOException ex) { ex.printStackTrace(); }
4. New I/O API
Java新的I/O API或NIO(java.nio.*包中的类)提供了Files.readAllLines()
方法来将文本文件逐行读取到List <String>
中,以下所示:
try { // read all lines List<String> lines = Files.readAllLines(Paths.get("examplefile.txt")); // print all lines lines.forEach(System.out::println); } catch (IOException ex) { ex.printStackTrace(); }
5. RandomAccessFile
RandomAccessFile类提供读写文件的非阻塞模式。 随机访问文件的行为相似于存储在文件系统中的大字节数组。
咱们可使用RandomAccessFile
以读取模式打开文件,而后使用其readLine()
方法逐行读取:
try { // open file in read mode RandomAccessFile file = new RandomAccessFile("examplefile.txt", "r"); // read until end of file String line; while ((line = file.readLine()) != null) { System.out.println(line); } // close the file file.close(); } catch (IOException ex) { ex.printStackTrace(); }
6. Apache Commons IO
Apache Commons IO库包含实用程序类,流实现,文件过滤器,文件比较器等。 将如下内容添加到build.gradle
文件中,以将库导入项目中:
implementation 'commons-io:commons-io:2.6'
若是您使用的是Maven,请将如下内容添加到·pom.xml·文件中:
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency>
如今,咱们可使用FileUtils.readLines()
(来自Apache Commons IO的静态方法)将文件中的全部行读取到List <String>
中:
try { // read all lines of a file List<String> lines = FileUtils.readLines(Paths.get("examplefile.txt").toFile(), "UTF-8"); // process the lines for (String line : lines) { System.out.println(line); } } catch (IOException ex) { ex.printStackTrace(); }
因为Apache Commons IO一次读取文件中的全部行,所以对于读取大文件而言,这可能不是一个好的解决方案。 在上述状况下,它将继续阻止for循环执行,直到将全部行添加到lines
对象为止。
7.Okie
Okie是由Square为Android,Kotlin和Java开发的另外一个开源I/O库。 它补充了本机java.io
和java.nio
包,使访问,保存和处理数据变得更加容易。
要在项目中导入Okie,请将如下内容添加到build.gradle文件中:
implementation 'com.squareup.okio:okio:2.4.0'
若是您使用的是Maven,请将如下内容添加到pom.xml
文件中:
<dependency> <groupId>com.squareup.okio</groupId> <artifactId>okio</artifactId> <version>2.4.0</version> </dependency>
如今,咱们可使用Okio.source()
方法打开源流以读取文件。 返回的Source
接口很小,用途有限。 Okie
提供了BufferedSource
类来用缓冲区包装源,从而使程序运行更快。
让咱们举个例子:
try { // open a source stream Source source = Okio.source(Paths.get("examplefile.txt").toFile()); // wrap stream with a buffer BufferedSource bs = Okio.buffer(source); // read until end of file String line; while ((line = bs.readUtf8Line()) != null) { System.out.println(line); } // close the stream source.close(); } catch (IOException ex) { ex.printStackTrace(); }
readUtf8Line()
方法读取数据,直到下一行分隔符– \ n
,\ r \ n
或文件的末尾。 它以字符串形式返回该数据,并在最后省略定界符。 当遇到空行时,该方法将返回一个空字符串。 若是没有更多的数据可读取,它将返回null
。
进一步阅读
您可能对其余Java I/O文章感兴趣:
- Reading and Writing Files in Java
- How to Read and Write Text Files in Java
- How to Read and Write Binary Files in Java
- Reading and Writing Files using Java NIO API
Like️喜欢这篇文章吗? 在Twitter和LinkedIn上关注我。 您也能够订阅RSS Feed。
上次更新:2020年2月18日
Java
您可能还喜欢…
- Remove the last character of a string in Java
- How to reverse the elements of a stream in Java
- How to extract digits from a string in Java
- How to read and parse a CSV file in Java
- Calculate difference between two dates in Java
本文同步分享在 博客“雪域迷影”(CSDN)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。