ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 在 Java 中读取文本文件 原文:http://zetcode.com/java/readtext/ 在 Java 中阅读文本文件教程中,我们展示了如何在 Java 中阅读文本文件。 我们使用内置工具,包括`FileReader`,`InputStreamReader`和`Scanner`。 另外,我们使用 API​​ Google Guava 库。 Google Guava 是 Java 的通用库集; 该集合也包括 IO API。 以下示例使用此文本文件。 `src/resources/thermopylae.txt` ```java The Battle of Thermopylae was fought between an alliance of Greek city-states, led by King Leonidas of Sparta, and the Persian Empire of Xerxes I over the 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` ```java package com.zetcode; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.nio.charset.StandardCharsets; public class FileReaderEx { public static void main(String[] args) throws IOException { var fileName = "src/resources/thermopylae.txt"; try (BufferedReader br = new BufferedReader( new FileReader(fileName, StandardCharsets.UTF_8))) { var sb = new StringBuilder(); String line; while ((line = br.readLine()) != null) { sb.append(line); sb.append(System.lineSeparator()); } System.out.println(sb); } } } ``` 该代码示例从`thermopylae.txt`文件读取文本。 ```java var fileName = "src/resources/thermopylae.txt"; ``` 在`fileName`变量中,我们存储文件的路径。 ```java try (BufferedReader br = new BufferedReader( new FileReader(fileName, StandardCharsets.UTF_8))) { ``` `FileReader`将文件名作为第一个参数。 第二个参数是使用的字符集。 `FileReader`传递给`BufferedReader`,后者缓冲读取操作以获得更好的性能。 这是一个`try-with-resources`语句,可确保在语句末尾关闭资源(缓冲的读取器)。 ```java var sb = new StringBuilder(); String line; while ((line = br.readLine()) != null) { sb.append(line); sb.append(System.lineSeparator()); } System.out.println(sb); ``` 在控制台上打印行会占用更多资源。 因此,我们使用`StringBuilder`构建输出字符串并在一个操作中将其打印出来。 这是一个可选的优化。 `System.lineSeparator()`返回系统相关的行分隔符字符串。 ## Java 使用`Files.readAllLines`读取文本文件 `Files.readAllLines()`方法从文件读取所有行。 此方法可确保在读取所有字节或引发异常后关闭文件。 使用指定的字符集将文件中的字节解码为字符。 请注意,此方法将整个文件读入内存。 因此,它可能不适用于非常大的文件。 `com/zetcode/ReadAllLinesEx.java` ```java package com.zetcode; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.List; public class ReadAllLinesEx { public static void main(String[] args) throws IOException { var fileName = "src/resources/thermopylae.txt"; List<String> lines = Files.readAllLines(Paths.get(fileName), StandardCharsets.UTF_8); for (String line : lines) { System.out.println(line); } } } ``` 使用`Files.readAllLines()`方法读取`thermopylae.txt`文件的内容并将其打印到控制台。 ## 使用 Java8 流 API 读取文本文件 读取文本文件的另一种方法是使用 Java8 流 API。 `Files.lines()`从文件中读取所有行作为流。 使用`StandardCharsets.UTF-8`字符集将文件中的字节解码为字符。 `com/zetcode/FilesLinesEx.java` ```java package com.zetcode; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; public class FilesLinesEx { public static void main(String[] args) throws IOException { var fileName = "src/resources/thermopylae.txt"; Files.lines(Paths.get(fileName)).forEachOrdered(System.out::println); } } ``` 使用`Files.lines()`方法读取`thermopylae.txt`文件的内容并将其打印到控制台。 ## Java 使用`Scanner`读取文本文件 `Scanner`是简单的文本扫描器,可以使用正则表达式解析原始类型和字符串。 `com/zetcode/ScannerEx.java` ```java package com.zetcode; import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class ScannerEx { public static void main(String[] args) throws FileNotFoundException { var fileName = "src/resources/thermopylae.txt"; try (var scanner = new Scanner(new File(fileName))) { while (scanner.hasNext()) { String line = scanner.nextLine(); System.out.println(line); } } } } ``` 该示例使用`Scanner`读取文本文件。 ```java while (scanner.hasNext()) { String line = scanner.nextLine(); System.out.println(line); } ``` 使用`nextLine()`方法逐行读取文件。 ## Java 使用`InputStreamReader`读取文本文件 `InputStreamReader`是从字节流到字符流的桥梁。 它读取字节,并使用指定的字符集将其解码为字符。 `com/zetcode/InputStreamReaderEx.java` ```java package com.zetcode; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; public class InputStreamReaderEx { public static void main(String[] args) throws IOException { var fileName = "src/resources/thermopylae.txt"; try (var br = new BufferedReader(new InputStreamReader( new FileInputStream(fileName), StandardCharsets.UTF_8))) { String line; while ((line = br.readLine()) != null) { System.out.println(line); } } } } ``` 该示例使用`InputStreamReader`读取文本文件。 ```java try (var br = new BufferedReader(new InputStreamReader( new FileInputStream(fileName), StandardCharsets.UTF_8))) { ``` `InputStreamReader`是从`FileInputStream`创建的,它通过打开与实际文件的连接来创建输入流。 然后将`InputStreamReader`传递给`BufferedReader`,以提高效率。 Java 7 引入了更方便的 API 来与`InputStreamReader`一起使用。 可以使用`Files.newBufferedReader`创建新的缓冲`InputStreamReader`。 `com/zetcode/InputStreamReaderEx2.java` ```java package com.zetcode; import java.io.BufferedReader; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; public class InputStreamReaderEx2 { public static void main(String[] args) throws IOException { var fileName = "src/resources/thermopylae.txt"; var filePath = Paths.get(fileName); try (BufferedReader br = Files.newBufferedReader( filePath, StandardCharsets.UTF_8)) { String line; while ((line = br.readLine()) != null) { System.out.println(line); } } } } ``` 该示例使用`Files.newBufferedReader()`方法读取`thermopylae.txt`文件。 ## Java 使用`Files.readAllBytes`读取文本文件 `Files.readAllBytes()`方法从文件读取所有字节。 它确保在读取所有字节后关闭文件。 `com/zetcode/ReadAllBytesEx.java` ```java package com.zetcode; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; public class ReadAllBytesEx { public static void main(String[] args) throws IOException { var fileName = "src/resources/thermopylae.txt"; var filePath = Paths.get(fileName); byte[] data = Files.readAllBytes(filePath); var content = new String(data); System.out.println(content); } } ``` 该示例从文件读取所有字节,并将它们传递给`String`构造器。 ## Java 使用`Files.readString`读取文本 Java 11 引入了一种方便的方法,该方法允许一次性将整个文件读取为字符串。 `Files.readString`将文件中的所有内容读取为字符串,并使用指定的或默认的(`StandardCharsets.UTF_8`)字符集将字节解码为字符。 它确保在读取所有内容后关闭文件。 `com/zetcode/ReadFileAsStringEx.java` ```java package com.zetcode; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; public class ReadFileAsStringEx { public static void main(String[] args) throws IOException { var fileName = "src/resources/thermopylae.txt"; var filePath = Paths.get(fileName); var content = Files.readString(filePath); System.out.println(content); } } ``` 该示例将`thermopylae.txt`文件的内容读取为字符串,然后将其打印到终端。 ## Java 使用`FileChannel`读取文本文件 `FileChannel`是用于读取,写入,映射和操作文件的通道。 文件通道的优点包括在文件的特定位置进行读写,加载文件的一部分或锁定文件的一部分。 `com/zetcode/FileChannelEx.java` ```java package com.zetcode; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class FileChannelEx { public static void main(String[] args) throws IOException { var fileName = "src/resources/thermopylae.txt"; try (RandomAccessFile myFile = new RandomAccessFile(fileName, "rw"); FileChannel inChannel = myFile.getChannel()) { ByteBuffer buf = ByteBuffer.allocate(48); int bytesRead = inChannel.read(buf); while (bytesRead != -1) { buf.flip(); while (buf.hasRemaining()) { System.out.print((char) buf.get()); } buf.clear(); bytesRead = inChannel.read(buf); } } } } ``` 该示例使用`FileChannel`读取文本文件。 ```java try (RandomAccessFile myFile = new RandomAccessFile(fileName, "rw"); FileChannel inChannel = myFile.getChannel()) { ``` 从`RandomAccessFile`创建一个`FileChannle`。 ```java ByteBuffer buf = ByteBuffer.allocate(48); int bytesRead = inChannel.read(buf); ``` 我们分配一个缓冲区并读取初始数据。 ```java while (bytesRead != -1) { buf.flip(); while (buf.hasRemaining()) { System.out.print((char) buf.get()); } buf.clear(); bytesRead = inChannel.read(buf); } ``` 我们将数据读入缓冲区并将其写入终端。 我们使用`flip()`将缓冲区从读取更改为写入。 ## 使用 Google Guava 读取文本文件 Google Guava 是一个 Java 帮助程序库,也具有 IO 工具。 如果要读取的文件很大,则以下两个 Guava 方法将消耗大量系统资源。 `pom.xml` ```java <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.zetcode</groupId> <artifactId>readtextguavaex</artifactId> <version>1.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>12</maven.compiler.source> <maven.compiler.target>12</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>28.0-jre</version> </dependency> </dependencies> </project> ``` 这是 Maven POM 文件。 `com/zetcode/ReadTextGuavaEx.java` ```java package com.zetcode; import com.google.common.base.Charsets; import com.google.common.io.Files; import java.io.File; import java.io.IOException; import java.util.List; public class ReadTextGuavaEx { public static void main(String[] args) throws IOException { var fileName = "src/main/resources/thermopylae.txt"; List<String> lines = Files.readLines(new File(fileName), Charsets.UTF_8); var sb = new StringBuilder(); for (String line: lines) { sb.append(line); sb.append(System.lineSeparator()); } System.out.println(sb); } } ``` 在示例中,我们使用`Files.readLines()`方法从文件中读取所有行。 该方法返回字符串列表。 将默认字符集指定为第二个参数。 在第二个示例中,我们使用`Files.asCharSource()`。 `com/zetcode/ReadTextGuavaEx2.java` ```java package com.zetcode; import com.google.common.base.Charsets; import com.google.common.io.Files; import java.io.File; import java.io.IOException; public class ReadTextGuavaEx2 { public static void main(String[] args) throws IOException { var fileName = "src/main/resources/thermopylae.txt"; var charSource = Files.asCharSource(new File(fileName), Charsets.UTF_8).read(); System.out.println(charSource); } } ``` `Files.asCharSource()`用于使用给定的字符集从给定的文件读取字符数据。 它的`read()`方法以字符串形式读取此源的内容。 在本文中,我们已经用 Java 的各种方式读取了文本文件。 您可能也对以下相关教程感兴趣: [Java 列表目录内容](/articles/javalistdirectory/), [Java `FileOutputStream`教程](/java/fileoutputstream/),[用 Java 复制文件](/java/copyfile/), [Java 教程](/lang/java/),[使用 Java8 的`StringJoiner`连接字符串](/articles/java8stringjoiner/) ,[Java 网页读取](/articles/javareadwebpage/)或 [Google Guava 简介](/articles/guava/)。 列出[所有 Java 教程](/all/#java)。