原文:http://zetcode.com/java/readtext/

在 Java 中阅读文本文件教程中,我们展示了如何在 Java 中阅读文本文件。 我们使用内置工具,包括FileReaderInputStreamReaderScanner。 另外,我们使用 API Google Guava 库。

Google Guava 是 Java 的通用库集; 该集合也包括 IO API。

以下示例使用此文本文件。

src/resources/thermopylae.txt

  1. The Battle of Thermopylae was fought between an alliance of Greek city-states,
  2. led by King Leonidas of Sparta, and the Persian Empire of Xerxes I over the
  3. course of three days, during the second Persian invasion of Greece.

该文件位于src/resources/目录中。

Java FileReader

我们可以使用以下 Java 类来读取 Java 中的文本文件。

  • java.io.FileReader
  • java.nio.file.Files
  • java.util.Scanner
  • java.io.InputStreamReader
  • com.google.common.io.Files

Java 使用FileReader读取文本文件

FileReader是用于读取字符文件的类。 它使用默认缓冲区大小从字符文件中读取文本。 从字节到字符的解码使用指定的字符集或平台的默认字符集。

注意:过去,FileReader依赖于默认平台的编码。 从 Java 11 开始,此问题已得到纠正。 现在可以显式指定编码。

com/zetcode/FileReaderEx.java

  1. package com.zetcode;
  2. import java.io.BufferedReader;
  3. import java.io.FileReader;
  4. import java.io.IOException;
  5. import java.nio.charset.StandardCharsets;
  6. public class FileReaderEx {
  7. public static void main(String[] args) throws IOException {
  8. var fileName = "src/resources/thermopylae.txt";
  9. try (BufferedReader br = new BufferedReader(
  10. new FileReader(fileName, StandardCharsets.UTF_8))) {
  11. var sb = new StringBuilder();
  12. String line;
  13. while ((line = br.readLine()) != null) {
  14. sb.append(line);
  15. sb.append(System.lineSeparator());
  16. }
  17. System.out.println(sb);
  18. }
  19. }
  20. }

该代码示例从thermopylae.txt文件读取文本。

  1. var fileName = "src/resources/thermopylae.txt";

fileName变量中,我们存储文件的路径。

  1. try (BufferedReader br = new BufferedReader(
  2. new FileReader(fileName, StandardCharsets.UTF_8))) {

FileReader将文件名作为第一个参数。 第二个参数是使用的字符集。 FileReader传递给BufferedReader,后者缓冲读取操作以获得更好的性能。 这是一个try-with-resources语句,可确保在语句末尾关闭资源(缓冲的读取器)。

  1. var sb = new StringBuilder();
  2. String line;
  3. while ((line = br.readLine()) != null) {
  4. sb.append(line);
  5. sb.append(System.lineSeparator());
  6. }
  7. System.out.println(sb);

在控制台上打印行会占用更多资源。 因此,我们使用StringBuilder构建输出字符串并在一个操作中将其打印出来。 这是一个可选的优化。 System.lineSeparator()返回系统相关的行分隔符字符串。

Java 使用Files.readAllLines读取文本文件

Files.readAllLines()方法从文件读取所有行。 此方法可确保在读取所有字节或引发异常后关闭文件。 使用指定的字符集将文件中的字节解码为字符。

请注意,此方法将整个文件读入内存。 因此,它可能不适用于非常大的文件。

com/zetcode/ReadAllLinesEx.java

  1. package com.zetcode;
  2. import java.io.IOException;
  3. import java.nio.charset.StandardCharsets;
  4. import java.nio.file.Files;
  5. import java.nio.file.Paths;
  6. import java.util.List;
  7. public class ReadAllLinesEx {
  8. public static void main(String[] args) throws IOException {
  9. var fileName = "src/resources/thermopylae.txt";
  10. List<String> lines = Files.readAllLines(Paths.get(fileName),
  11. StandardCharsets.UTF_8);
  12. for (String line : lines) {
  13. System.out.println(line);
  14. }
  15. }
  16. }

使用Files.readAllLines()方法读取thermopylae.txt文件的内容并将其打印到控制台。

使用 Java8 流 API 读取文本文件

读取文本文件的另一种方法是使用 Java8 流 API。 Files.lines()从文件中读取所有行作为流。 使用StandardCharsets.UTF-8字符集将文件中的字节解码为字符。

com/zetcode/FilesLinesEx.java

  1. package com.zetcode;
  2. import java.io.IOException;
  3. import java.nio.file.Files;
  4. import java.nio.file.Paths;
  5. public class FilesLinesEx {
  6. public static void main(String[] args) throws IOException {
  7. var fileName = "src/resources/thermopylae.txt";
  8. Files.lines(Paths.get(fileName)).forEachOrdered(System.out::println);
  9. }
  10. }

使用Files.lines()方法读取thermopylae.txt文件的内容并将其打印到控制台。

Java 使用Scanner读取文本文件

Scanner是简单的文本扫描器,可以使用正则表达式解析原始类型和字符串。

com/zetcode/ScannerEx.java

  1. package com.zetcode;
  2. import java.io.File;
  3. import java.io.FileNotFoundException;
  4. import java.util.Scanner;
  5. public class ScannerEx {
  6. public static void main(String[] args) throws FileNotFoundException {
  7. var fileName = "src/resources/thermopylae.txt";
  8. try (var scanner = new Scanner(new File(fileName))) {
  9. while (scanner.hasNext()) {
  10. String line = scanner.nextLine();
  11. System.out.println(line);
  12. }
  13. }
  14. }
  15. }

该示例使用Scanner读取文本文件。

  1. while (scanner.hasNext()) {
  2. String line = scanner.nextLine();
  3. System.out.println(line);
  4. }

使用nextLine()方法逐行读取文件。

Java 使用InputStreamReader读取文本文件

InputStreamReader是从字节流到字符流的桥梁。 它读取字节,并使用指定的字符集将其解码为字符。

com/zetcode/InputStreamReaderEx.java

  1. package com.zetcode;
  2. import java.io.BufferedReader;
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.IOException;
  6. import java.io.InputStreamReader;
  7. import java.nio.charset.StandardCharsets;
  8. public class InputStreamReaderEx {
  9. public static void main(String[] args) throws IOException {
  10. var fileName = "src/resources/thermopylae.txt";
  11. try (var br = new BufferedReader(new InputStreamReader(
  12. new FileInputStream(fileName), StandardCharsets.UTF_8))) {
  13. String line;
  14. while ((line = br.readLine()) != null) {
  15. System.out.println(line);
  16. }
  17. }
  18. }
  19. }

该示例使用InputStreamReader读取文本文件。

  1. try (var br = new BufferedReader(new InputStreamReader(
  2. new FileInputStream(fileName), StandardCharsets.UTF_8))) {

InputStreamReader是从FileInputStream创建的,它通过打开与实际文件的连接来创建输入流。 然后将InputStreamReader传递给BufferedReader,以提高效率。

Java 7 引入了更方便的 API 来与InputStreamReader一起使用。 可以使用Files.newBufferedReader创建新的缓冲InputStreamReader

com/zetcode/InputStreamReaderEx2.java

  1. package com.zetcode;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.nio.charset.StandardCharsets;
  5. import java.nio.file.Files;
  6. import java.nio.file.Paths;
  7. public class InputStreamReaderEx2 {
  8. public static void main(String[] args) throws IOException {
  9. var fileName = "src/resources/thermopylae.txt";
  10. var filePath = Paths.get(fileName);
  11. try (BufferedReader br = Files.newBufferedReader(
  12. filePath, StandardCharsets.UTF_8)) {
  13. String line;
  14. while ((line = br.readLine()) != null) {
  15. System.out.println(line);
  16. }
  17. }
  18. }
  19. }

该示例使用Files.newBufferedReader()方法读取thermopylae.txt文件。

Java 使用Files.readAllBytes读取文本文件

Files.readAllBytes()方法从文件读取所有字节。 它确保在读取所有字节后关闭文件。

com/zetcode/ReadAllBytesEx.java

  1. package com.zetcode;
  2. import java.io.IOException;
  3. import java.nio.file.Files;
  4. import java.nio.file.Paths;
  5. public class ReadAllBytesEx {
  6. public static void main(String[] args) throws IOException {
  7. var fileName = "src/resources/thermopylae.txt";
  8. var filePath = Paths.get(fileName);
  9. byte[] data = Files.readAllBytes(filePath);
  10. var content = new String(data);
  11. System.out.println(content);
  12. }
  13. }

该示例从文件读取所有字节,并将它们传递给String构造器。

Java 使用Files.readString读取文本

Java 11 引入了一种方便的方法,该方法允许一次性将整个文件读取为字符串。

Files.readString将文件中的所有内容读取为字符串,并使用指定的或默认的(StandardCharsets.UTF_8)字符集将字节解码为字符。 它确保在读取所有内容后关闭文件。

com/zetcode/ReadFileAsStringEx.java

  1. package com.zetcode;
  2. import java.io.IOException;
  3. import java.nio.file.Files;
  4. import java.nio.file.Paths;
  5. public class ReadFileAsStringEx {
  6. public static void main(String[] args) throws IOException {
  7. var fileName = "src/resources/thermopylae.txt";
  8. var filePath = Paths.get(fileName);
  9. var content = Files.readString(filePath);
  10. System.out.println(content);
  11. }
  12. }

该示例将thermopylae.txt文件的内容读取为字符串,然后将其打印到终端。

Java 使用FileChannel读取文本文件

FileChannel是用于读取,写入,映射和操作文件的通道。 文件通道的优点包括在文件的特定位置进行读写,加载文件的一部分或锁定文件的一部分。

com/zetcode/FileChannelEx.java

  1. package com.zetcode;
  2. import java.io.IOException;
  3. import java.io.RandomAccessFile;
  4. import java.nio.ByteBuffer;
  5. import java.nio.channels.FileChannel;
  6. public class FileChannelEx {
  7. public static void main(String[] args) throws IOException {
  8. var fileName = "src/resources/thermopylae.txt";
  9. try (RandomAccessFile myFile = new RandomAccessFile(fileName, "rw");
  10. FileChannel inChannel = myFile.getChannel()) {
  11. ByteBuffer buf = ByteBuffer.allocate(48);
  12. int bytesRead = inChannel.read(buf);
  13. while (bytesRead != -1) {
  14. buf.flip();
  15. while (buf.hasRemaining()) {
  16. System.out.print((char) buf.get());
  17. }
  18. buf.clear();
  19. bytesRead = inChannel.read(buf);
  20. }
  21. }
  22. }
  23. }

该示例使用FileChannel读取文本文件。

  1. try (RandomAccessFile myFile = new RandomAccessFile(fileName, "rw");
  2. FileChannel inChannel = myFile.getChannel()) {

RandomAccessFile创建一个FileChannle

  1. ByteBuffer buf = ByteBuffer.allocate(48);
  2. int bytesRead = inChannel.read(buf);

我们分配一个缓冲区并读取初始数据。

  1. while (bytesRead != -1) {
  2. buf.flip();
  3. while (buf.hasRemaining()) {
  4. System.out.print((char) buf.get());
  5. }
  6. buf.clear();
  7. bytesRead = inChannel.read(buf);
  8. }

我们将数据读入缓冲区并将其写入终端。 我们使用flip()将缓冲区从读取更改为写入。

使用 Google Guava 读取文本文件

Google Guava 是一个 Java 帮助程序库,也具有 IO 工具。 如果要读取的文件很大,则以下两个 Guava 方法将消耗大量系统资源。

pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  5. http://maven.apache.org/xsd/maven-4.0.0.xsd">
  6. <modelVersion>4.0.0</modelVersion>
  7. <groupId>com.zetcode</groupId>
  8. <artifactId>readtextguavaex</artifactId>
  9. <version>1.0-SNAPSHOT</version>
  10. <properties>
  11. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  12. <maven.compiler.source>12</maven.compiler.source>
  13. <maven.compiler.target>12</maven.compiler.target>
  14. </properties>
  15. <dependencies>
  16. <dependency>
  17. <groupId>com.google.guava</groupId>
  18. <artifactId>guava</artifactId>
  19. <version>28.0-jre</version>
  20. </dependency>
  21. </dependencies>
  22. </project>

这是 Maven POM 文件。

com/zetcode/ReadTextGuavaEx.java

  1. package com.zetcode;
  2. import com.google.common.base.Charsets;
  3. import com.google.common.io.Files;
  4. import java.io.File;
  5. import java.io.IOException;
  6. import java.util.List;
  7. public class ReadTextGuavaEx {
  8. public static void main(String[] args) throws IOException {
  9. var fileName = "src/main/resources/thermopylae.txt";
  10. List<String> lines = Files.readLines(new File(fileName),
  11. Charsets.UTF_8);
  12. var sb = new StringBuilder();
  13. for (String line: lines) {
  14. sb.append(line);
  15. sb.append(System.lineSeparator());
  16. }
  17. System.out.println(sb);
  18. }
  19. }

在示例中,我们使用Files.readLines()方法从文件中读取所有行。 该方法返回字符串列表。 将默认字符集指定为第二个参数。

在第二个示例中,我们使用Files.asCharSource()

com/zetcode/ReadTextGuavaEx2.java

  1. package com.zetcode;
  2. import com.google.common.base.Charsets;
  3. import com.google.common.io.Files;
  4. import java.io.File;
  5. import java.io.IOException;
  6. public class ReadTextGuavaEx2 {
  7. public static void main(String[] args) throws IOException {
  8. var fileName = "src/main/resources/thermopylae.txt";
  9. var charSource = Files.asCharSource(new File(fileName),
  10. Charsets.UTF_8).read();
  11. System.out.println(charSource);
  12. }
  13. }

Files.asCharSource()用于使用给定的字符集从给定的文件读取字符数据。 它的read()方法以字符串形式读取此源的内容。

在本文中,我们已经用 Java 的各种方式读取了文本文件。

您可能也对以下相关教程感兴趣: Java 列表目录内容Java FileOutputStream教程用 Java 复制文件Java 教程使用 Java8 的StringJoiner连接字符串Java 网页读取Google Guava 简介

列出所有 Java 教程