【JavaEE初阶】告别小白!Java IO 流读写 + 文件操作实战

【JavaEE初阶】告别小白!Java IO 流读写 + 文件操作实战(2026最实用版)

Java IO 是很多初学者觉得“最乱、最难记、最容易出错”的部分,但其实只要抓住“四个家族 + 三个装饰” 这个核心框架,后面写任何文件操作都会变得非常有章法。

一、先记住这个最核心的“四大家族”分类表(背下来就成功一半)

流向字节流(8bit)字符流(16bit)主要使用场景推荐度(2026)
输入InputStreamReader读文件、网络、键盘★★★★★
输出OutputStreamWriter写文件、网络、屏幕★★★★★
文件专用FileInputStreamFileReader直接操作文件(最常用)★★★★☆
缓冲BufferedInputStreamBufferedReader / BufferedWriter日常读写文件强烈推荐★★★★★
转换InputStreamReaderOutputStreamWriter字节流 → 字符流(处理编码问题)★★★★☆
内存ByteArrayInputStream / …CharArrayReader / …内存中模拟文件(测试/临时数据)★★☆☆☆
数据DataInputStream / DataOutputStream读写基本数据类型(int、double等)★★★☆☆
对象ObjectInputStream / ObjectOutputStream序列化/反序列化对象★★★★☆

最常用的黄金组合(记住这四组,90%的业务场景够用)

  1. BufferedReader + FileReader → 按行高效读文本文件
  2. BufferedWriter + FileWriter → 按行高效写文本文件
  3. BufferedInputStream + FileInputStream → 高效读二进制文件(图片、视频、压缩包)
  4. BufferedOutputStream + FileOutputStream → 高效写二进制文件

二、2026年最推荐的几种写法对比(强烈建议用第4种)

// 写法1:最原始(极少用,效率低)
try (FileInputStream fis = new FileInputStream("a.txt")) {
    int data;
    while ((data = fis.read()) != -1) {
        System.out.print((char)data);
    }
} catch (IOException e) { ... }

// 写法2:带缓冲(推荐!最常用)
try (BufferedReader br = new BufferedReader(new FileReader("user.csv"))) {
    String line;
    while ((line = br.readLine()) != null) {
        System.out.println(line);
    }
} catch (IOException e) { ... }

// 写法3:一行读取全部(适合小文件)
try {
    String content = Files.readString(Path.of("config.json"));
    // 或 List<String> lines = Files.readAllLines(...)
} catch (IOException e) { ... }

// 写法4:2026年终极推荐写法(NIO.2 + try-with-resources)
try {
    // 读全部文本(超方便)
    String content = Files.readString(Path.of("notes.md"), StandardCharsets.UTF_8);

    // 读所有行
    List<String> lines = Files.readAllLines(Path.of("log.txt"));

    // 写文件(覆盖)
    Files.writeString(Path.of("output.txt"), "新内容...\n第二行", StandardCharsets.UTF_8);

    // 追加写
    Files.writeString(Path.of("append.log"), "追加一条\n", StandardCharsets.UTF_8, StandardOpenOption.APPEND);

    // 复制文件(最快)
    Files.copy(Path.of("source.jpg"), Path.of("backup.jpg"), StandardCopyOption.REPLACE_EXISTING);

} catch (IOException e) {
    e.printStackTrace();
}

三、经典实战案例(建议全部敲一遍)

案例1:统计文件中出现次数最多的单词(面试/练习高频)

public static void main(String[] args) throws IOException {
    Path path = Path.of("english.txt");
    String content = Files.readString(path, StandardCharsets.UTF_8);

    // 简单分词(实际项目建议用更专业的分词库)
    Map<String, Long> wordCount = Arrays.stream(content.toLowerCase().split("\\W+"))
            .filter(word -> !word.isBlank())
            .collect(Collectors.groupingBy(
                    Function.identity(),
                    Collectors.counting()
            ));

    // 找出出现次数最多的词
    wordCount.entrySet().stream()
            .max(Map.Entry.comparingByValue())
            .ifPresent(e -> System.out.println("最常见单词:" + e.getKey() + " 出现 " + e.getValue() + " 次"));
}

案例2:大文件逐行处理(内存友好版)

try (BufferedReader reader = Files.newBufferedReader(Path.of("very-big.log"), StandardCharsets.UTF_8)) {
    String line;
    long lineNumber = 0;
    while ((line = reader.readLine()) != null) {
        lineNumber++;
        if (line.contains("ERROR")) {
            System.out.printf("第 %d 行发现错误: %s%n", lineNumber, line);
        }
    }
}

案例3:复制文件(带进度条风格提示)

public static void copyFileWithProgress(Path source, Path target) throws IOException {
    long totalBytes = Files.size(source);
    long copied = 0;

    try (InputStream in = Files.newInputStream(source);
         OutputStream out = Files.newOutputStream(target);
         BufferedInputStream bin = new BufferedInputStream(in);
         BufferedOutputStream bout = new BufferedOutputStream(out)) {

        byte[] buffer = new byte[8192];
        int len;
        while ((len = bin.read(buffer)) != -1) {
            bout.write(buffer, 0, len);
            copied += len;
            System.out.printf("\r进度: %.2f%%", (copied * 100.0 / totalBytes));
        }
    }
    System.out.println("\n复制完成!");
}

四、2026年最常踩的坑 & 避坑口诀

  1. 永远用 try-with-resources(自动关闭流)
  2. 指定字符编码(尤其是中文环境用 UTF-8)
  3. 大文件别 readAllBytes() / readString() → 内存爆炸
  4. 路径问题:优先使用 Path.of() + Files 而不是 new File()
  5. Windows换行符:写文件时建议用 BufferedWriter.newLine() 而不是硬写 \n
  6. 不要在finally里close → try-with-resources 已经帮你处理了

五、进阶快速路线建议(掌握顺序)

第1阶段:熟练使用 FilesPathBufferedReader/Writer
第2阶段:掌握 InputStream/OutputStream + 缓冲包装
第3阶段:序列化(ObjectStream)与 transient 关键字
第4阶段:NIO.2(Channel、Buffer、FileLock)
第5阶段:Netty/Okio 等第三方高性能 IO 框架

一句话总结:
小文件 → Files类直接读写
中大文本文件 → BufferedReader/Writer
二进制/大文件 → Buffered*Stream
路径/文件操作 → java.nio.file.Files & Path

你现在最常写的文件操作场景是什么?
(日志读取、配置文件读写、Excel导入导出、图片上传处理……)
告诉我,我可以给你更针对性的代码模板~

文章已创建 3806

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部