当前位置:首页 > 后端开发 > 正文

java io怎么读取文本数据并保存

Scanner类读取文本数据,用 PrintWriterBufferedWriter将数据写入文件,通过 File对象指定路径完成操作

Java中,IO(Input/Output)操作是处理文件读写的核心机制,以下是关于如何读取文本数据并保存的详细讲解,涵盖多种实现方式、代码示例及注意事项:

读取文本数据的常用方法

基础字符流:FileReader

  • 原理:直接基于字符编码逐字符或批量读取文本内容,适合简单场景。
    File file = new File("input.txt");
    try (FileReader fr = new FileReader(file)) {
        int ch;
        while ((ch = fr.read()) != -1) { // 单次读一个字符
            System.out.print((char) ch);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    上述代码通过read()逐个读取字符直到返回-1(文件末尾),若需提高效率,可改用数组缓冲:

    char[] buffer = new char[1024];
    int len;
    while ((len = fr.read(buffer)) != -1) { // 批量读取到缓冲区
        String part = new String(buffer, 0, len);
        // 处理part逻辑...
    }
  • 特点:无需手动转换编码,默认使用平台默认字符集;但缺乏灵活性控制编码格式。

带缓冲的字符流:BufferedReader

  • 优势:内置缓存区减少频繁磁盘访问,显著提升性能,常与FileReader组合使用:
    try (BufferedReader br = new BufferedReader(new FileReader("largefile.log"))) {
        String line;
        while ((line = br.readLine()) != null) { // 按行读取
            System.out.println(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    readLine()方法会自动丢弃换行符,适用于日志分析等逐行处理场景。

    java io怎么读取文本数据并保存  第1张

NIO方式:Files工具类(Java 7+)

  • 简洁性:静态方法直接加载全部内容到内存,适合小型文件:
    List<String> lines = Files.readAllLines(Paths.get("poem.txt"));
    for (String line : lines) {
        System.out.println(line);
    }
    // 或读取为单个字符串
    String content = new String(Files.readAllBytes(Paths.get("note.txt")), StandardCharsets.UTF_8);
  • 注意:大文件慎用此方式,可能导致内存溢出。

保存文本数据的实现方案

基础写入:FileWriter

  • 基本用法:覆盖模式写入单一字符串:
    try (FileWriter fw = new FileWriter("output.txt")) {
        fw.write("Hello World");
    } catch (IOException e) {
        e.printStackTrace();
    }

    追加模式需设置构造函数第二个参数为true

    new FileWriter("app.log", true).write("New log entryn"); // 追加日志
  • 局限性:无缓冲机制,频繁落盘影响性能。

高效缓冲写入:BufferedWriter

  • 最佳实践:结合缓冲区批量刷新数据:
    try (BufferedWriter bw = new BufferedWriter(new FileWriter("report.doc"))) {
        bw.write("Section 1:...");
        bw.newLine(); // 跨平台换行符处理
        bw.write("Section 2:...");
    } catch (IOException e) {
        e.printStackTrace();
    }

    newLine()会根据系统自动适配nrn,比直接写入"n"更可靠。

字节级转换写入

  • 适用场景:需要精确控制编码时(如UTF-8转GBK):
    // 写入阶段:字符串→字节数组→文件
    byte[] utf8Data = "中文测试".getBytes(StandardCharsets.UTF_8);
    try (FileOutputStream fos = new FileOutputStream("chinese_text.dat")) {
        fos.write(utf8Data);
    }
    // 读取阶段:反向解码验证完整性
    byte[] storedBytes = Files.readAllBytes(Paths.get("chinese_text.dat"));
    String validatedStr = new String(storedBytes, StandardCharsets.UTF_8);
    assert validatedStr.equals("中文测试");

    此模式常用于跨系统兼容的数据交换。

关键注意事项对比表

维度 FileReader/FileWriter BufferedReader/BufferedWriter Files类
性能 低(无缓冲) 高(默认8KB缓存) 极高(全量加载)
适用文件大小 小型 中小型 仅限小型
编码可控性 依赖默认编码 同左 可指定Charset参数
API友好度 基础易上手 需管理缓冲区 最简捷
异常安全性 需手动close try-with-resources推荐 自动资源释放

完整示例:带编码指定的文本复制工具

import java.io.;
import java.nio.charset.StandardCharsets;
public class TextCopier {
    public static void main(String[] args) throws IOException {
        File src = new File("source.txt");
        File dest = new File("copy.txt");
        try (Reader reader = new InputStreamReader(new FileInputStream(src), StandardCharsets.UTF_8);
             Writer writer = new OutputStreamWriter(new FileOutputStream(dest), StandardCharsets.UTF_8)) {
             char[] buffer = new char[4096];
             int bytesRead;
             while ((bytesRead = reader.read(buffer)) != -1) {
                 writer.write(buffer, 0, bytesRead);
             }
         }
    }
}

该实现确保了:
① 显式指定UTF-8编码避免乱码;
② 使用NIO转换流统一处理字节/字符转换;
③ try-with-resources语法保证资源释放。


FAQs

Q1: 为什么有时读取中文会出现乱码?如何处理?
A: 因为未正确设置字符集,解决方案是在创建流时明确指定编码格式,new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8),读取时应使用相同的编码解析字节数组。

Q2: 大文件处理时内存不足怎么办?
A: 采用分块读取策略,例如每次读取固定大小的缓冲区(如4KB),而不是一次性加载整个文件,可通过循环控制单次I/O的数据量,配合缓冲流

0