Java读取文本文件——FileReader、InputStreamReader、FileInputStream

位置:首页>文章>详情   分类: Java教程 > 编程技术   阅读(261)   2023-06-26 07:54:18

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

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

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

src/resources/thermopylae.txt
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 读取文本类

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

  • java.io.文件读取器
  • java.nio.file.文件
  • java.util.扫描器
  • java.io.InputStreamReader
  • com.google.common.io.Files

Java 使用 FileReader 读取文本文件

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

笔记:过去,FileReader 依赖于默认平台的编码。自 Java 11 起,该问题已得到纠正。现在可以明确指定编码。
com/zetcode/FileReaderEx.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 文件中读取文本。

var fileName = "src/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 返回系统相关的行分隔符字符串。

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

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

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

com/zetcode/ReadAllLinesEx.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 文件的内容并将其打印到控制台。

使用 Java 8 流 API 读取文本文件

读取文本文件的另一种选择是使用 Java 8 流式 API。 Files.lines 将文件中的所有行作为流读取。使用 StandardCharsets.UTF-8 字符集将文件中的字节解码为字符。

com/zetcode/FilesLinesEx.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
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 读取文本文件。

while (scanner.hasNext()) {

    String line = scanner.nextLine();
    System.out.println(line);
}

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

Java 使用 InputStreamReader 读取文本文件

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

com/zetcode/InputStreamReaderEx.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 读取文本文件。

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
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
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
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
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 读取文本文件。

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

FileChannleRandomAccessFile 创建。

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 将缓冲区从读取更改为写入。

使用 Google Guava 读取文本文件

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

pom.xml
<?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
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
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 以各种方式读取文本文件。

List 所有 Java 教程.

地址:https://www.cundage.com/article/java-readtext.html

相关阅读

Spring Boot Vue.js 教程展示了如何使用 Vue.js 框架创建一个简单的 Spring Boot。 Vue.js Vue.js 是一个用于构建用户界面的 JavaScript ...
JavaScript 是否已经取代 Java 成为新的“一次编写,随处运行”的编程语言?这完全取决于您的观点。随着 WebAssembly 等技术的出现,Java 可以在新奇的“一次编写,随处编...
Usage of TypeScript,微软基于 JavaScript 的强类型语言, has soared compared to six years ago, according to th...
云莓将基于 Spring 构建的 Java 后端与使用 Lit 构建的 TypeScript 前端相结合,一个快速、响应式的 JavaScript 框架。基于 Vaadin Fusion 的 H...
本博客严重偏向于 GWT(和基于 GWT 的框架),但我们牢记 GWT 将来可能会被其他技术接管,因此我们始终对探索其他平台/框架持开放态度。正如他们所说,多元化可以降低风险。每种编程语言,即使...
Java JSON 教程展示了如何使用 JSON-Java 在 Java 中进行 JSON 序列化和反序列化。 JSON(JavaScript 对象显示法) 是一种轻量级数据交换格式。人类易于读...
JHipster 是一个长期存在且雄心勃勃的混合 Java 和 JavaScript 项目,致力于使用现代反应式前端简化全栈 Java 应用程序的开发。 JHipster 开发团队不断发布新版本...
解析器是强大的工具,使用 ANTLR 可以编写可用于多种不同语言的各种解析器。 在这个完整的教程中,我们将: 解释基础:什么是解析器,它可以用来做什么 查看如何设置 ANTLR 以便在 Java...
Spring Boot JSON 教程展示了如何在 Spring Boot 注释中提供 JSON 数据。 春天 是一个流行的 Java 应用程序框架,弹簧贴 是 Spring 的演变,有助于创建...
根据最近一项全球开发人员调查,在开发人员偏好方面,JavaScript 和 Python 保持了持久力,而 锈 的使用率正在上升. 5 月 4 日的一份题为“开发者国家情况,第 22nd 版”的...