在 Java 中读取文本文件
最后修改日期:2024 年 7 月 10 日
在 Java 中读取文本文件教程中,我们将展示如何在 Java 中读取文本文件。我们使用内置工具,包括 FileReader、InputStreamReader 和 Scanner。
以下示例使用此文本文件。
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/main/resources/ 目录中。
Java 读取文本类
我们可以使用以下 Java 类在 Java 中读取文本文件。
- java.io.FileReader
- java.nio.file.Files
- java.util.Scanner
- java.io.InputStreamReader
- com.google.common.io.Files
使用 FileReader 读取文本文件
FileReader 是用于读取字符文件的类。它使用默认缓冲区大小从字符文件中读取文本。从字节到字符的解码使用指定的字符集或平台的默认字符集。
FileReader 依赖于平台默认的编码。自 Java 11 以来,该问题已得到纠正。现在可以显式指定编码。import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
void main() throws IOException {
var fileName = "src/main/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 文件中读取文本。
var fileName = "src/main/resources/thermopylae.txt";
在 fileName 变量中,我们存储文件的路径。
try (BufferedReader br = new BufferedReader(
new FileReader(fileName, StandardCharsets.UTF_8))) {
FileReader 将文件名作为第一个参数。第二个参数是使用的字符集。FileReader 被传递给 BufferedReader,后者缓冲读取操作以获得更好的性能。这是一个 try-with-resources 语句,它确保资源(缓冲读取器)在语句末尾被关闭。
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 返回系统相关的行分隔符字符串。
使用 Files.readAllLines 读取文本文件
Files.readAllLines 方法读取文件中的所有行。此方法确保在读取所有字节或抛出异常时关闭文件。文件中的字节使用指定的字符集解码为字符。
请注意,此方法将整个文件读取到内存中;因此,它可能不适用于非常大的文件。
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
void main() throws IOException {
var fileName = "src/main/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 文件的内容并将其打印到控制台。
使用流式 API 读取文本文件
读取文本文件的另一种选择是使用 Java 流式 API。Files.lines 将文件中的所有行作为流读取。文件中的字节使用 StandardCharsets.UTF-8 字符集解码为字符。
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;
void main() throws IOException {
var fileName = "src/main/resources/thermopylae.txt";
var path = Paths.get(fileName);
try (Stream<String> lines = Files.lines(path)) {
lines.forEachOrdered(System.out::println);
}
}
使用 Files.lines 方法读取 thermopylae.txt 文件的内容并将其打印到控制台。
使用 Scanner 读取文本文件
Scanner 是一个简单的文本扫描器,可以使用正则表达式解析基本类型和字符串。
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
void main() throws FileNotFoundException {
var fileName = "src/main/resources/thermopylae.txt";
try (var scanner = new Scanner(new File(fileName))) {
while (scanner.hasNext()) {
String line = scanner.nextLine();
System.out.println(line);
}
}
}
该示例使用 Scanner 读取文本文件。
while (scanner.hasNext()) {
String line = scanner.nextLine();
System.out.println(line);
}
使用 nextLine 方法逐行读取文件。
使用 InputStreamReader 读取文本文件
InputStreamReader 是从字节流到字符流的桥梁。它读取字节并使用指定的字符集将它们解码为字符。
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
void main() throws IOException {
var fileName = "src/main/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 读取文本文件。
try (var br = new BufferedReader(new InputStreamReader(
new FileInputStream(fileName), StandardCharsets.UTF_8))) {
InputStreamReader 从 FileInputStream 创建,后者通过打开与实际文件的连接来创建输入流。然后将 InputStreamReader 传递给 BufferedReader 以提高效率。
Java 7 引入了一个更方便的 API 来使用 InputStreamReader。可以使用 Files.newBufferedReader 创建一个新的缓冲 InputStreamReader。
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
void main() throws IOException {
var fileName = "src/main/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 文件。
使用 Files.readAllBytes 读取文本文件
Files.readAllBytes 方法读取文件中的所有字节。它确保在读取所有字节时关闭文件。
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
void main() throws IOException {
var fileName = "src/main/resources/thermopylae.txt";
var filePath = Paths.get(fileName);
byte[] data = Files.readAllBytes(filePath);
var content = new String(data);
System.out.println(content);
}
该示例读取文件中的所有字节,并将它们传递给 String 构造函数。
使用 Files.readString 读取文本
Java 11 引入了一种方便的方法,允许一次性将整个文件读取到字符串中。
Files.readString 将文件中的所有内容读取到字符串中,使用指定的或默认的 (StandardCharsets.UTF_8) 字符集从字节解码为字符。它确保在读取所有内容后关闭文件。
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
void main() throws IOException {
var fileName = "src/main/resources/thermopylae.txt";
var filePath = Paths.get(fileName);
var content = Files.readString(filePath);
System.out.println(content);
}
该示例将 thermopylae.txt 文件的内容读取到字符串中,并将其打印到终端。
使用 FileChannel 读取文本文件
FileChannel 是用于读取、写入、映射和操作文件的通道。文件通道的优点包括在文件的特定位置读取和写入,加载文件的某个部分或锁定文件的某个部分。
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
void main() throws IOException {
var fileName = "src/main/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 读取文本文件。
try (RandomAccessFile myFile = new RandomAccessFile(fileName, "rw");
FileChannel inChannel = myFile.getChannel()) {
从 RandomAccessFile 创建 FileChannle。
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);
}
我们将数据读取到缓冲区中,并将其写入终端。我们使用 flip 将缓冲区从读取更改为写入。
来源
在本文中,我们以各种方式在 Java 中读取了文本文件。
作者
列出所有Java教程。