一、需求场景解析

本次竞赛题的核心是两种文件复制场景:

文本文件复制:专门处理 .txt/.java 等文本文件,推荐使用字符缓冲流

任意文件复制:支持图片、视频、压缩包等所有类型文件,推荐使用字节缓冲流

二、文本文件复制:字符缓冲流(BufferedReader/BufferedWriter)

字符缓冲流是处理文本文件的首选,自带缓冲区,读写效率极高,还支持按行读取的便捷操作

核心代码:

import java.io.*;

public class TextFileCopy {
    public static void main(String[] args) {
        // 源文件路径
        String srcPath = "src/original.txt";
        // 目标文件路径
        String destPath = "src/copy.txt";

        // try-with-resources 自动关闭流,避免资源泄漏
        try (BufferedReader br = new BufferedReader(new FileReader(srcPath));
             BufferedWriter bw = new BufferedWriter(new FileWriter(destPath))) {

            String line;
            // 按行读取文本文件
            while ((line = br.readLine()) != null) {
                bw.write(line);
                // 写入换行符(不同系统换行符不同,也可使用 bw.newLine())
                bw.newLine();
            }

            System.out.println("文本文件复制完成!");

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

关键知识点 BufferedReader.readLine():

按行读取文本,自动处理换行符,适合文本文件场景 BufferedWriter.newLine():

写入系统默认的换行符,跨平台兼容性更好 适用场景:

纯文本文件(.txt、.java、.html 等),不适合处理图片、视频等二进制文件

三、任意文件复制:字节缓冲流(BufferedInputStream/BufferedOutputStream)

字节流是 “万能流”,可以处理所有类型的文件,加上缓冲流后效率大幅提升,是文件复制的通用方案。

核心代码实现

import java.io.*;

public class AnyFileCopy {
    public static void main(String[] args) {
        // 源文件路径(支持图片、视频、压缩包等)
        String srcPath = "src/original.jpg";
        // 目标文件路径
        String destPath = "src/copy.jpg";

        // 定义缓冲区大小(常用 8KB 或 4KB)
        byte[] buffer = new byte[8192];

        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcPath));
             BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destPath))) {

            int len;
            // 循环读取文件数据到缓冲区
            while ((len = bis.read(buffer)) != -1) {
                // 将缓冲区的数据写入目标文件
                bos.write(buffer, 0, len);
            }

            System.out.println("文件复制完成!");

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

关键知识点

  • 字节流的本质:直接操作文件的二进制数据,不关心文件格式,因此支持所有类型文件
  • 缓冲区优化:byte[] buffer 减少了磁盘 IO 次数,大幅提升复制效率
  • bis.read(buffer):返回实际读取到的字节数,len == -1 表示文件读取完毕
  • bos.write(buffer, 0, len):写入时只写实际读取到的字节,避免缓冲区残留数据导致文件损坏

四、两种方案对比

对比项 字符缓冲流(BufferedReader/BufferedWriter) 字节缓冲流(BufferedInputStream/BufferedOutputStream)
适用文件类型 仅文本文件 所有类型文件(文本、图片、视频、压缩包等)
处理单位 字符(char) 字节(byte)
核心优势 按行读取文本,操作便捷,效率高 通用性强,二进制文件无乱码问题
典型场景 复制日志、配置文件、代码文件 复制图片、视频、安装包等任意文件
乱码风险 处理非文本文件会乱码 无乱码风险

五、竞赛题常见考点与优化技巧

1. 为什么要用缓冲流?

直接使用 FileInputStream/FileOutputStream 每次读写都要访问磁盘,效率极低;缓冲流会先将数据读到内存缓冲区,批量读写,减少磁盘 IO 次数,性能提升非常明显。

2. 缓冲区大小怎么选?

常用大小为 4KB(4096)或 8KB(8192),和磁盘扇区大小匹配,能最大化读写效率。过大的缓冲区会占用过多内存,过小则起不到优化效果。

3. try-with-resources 的重要性

必须使用 try-with-resources 语法自动关闭流,避免手动 close() 时出现异常导致资源泄漏,这也是 Java IO 编程的规范写法。

4. 文本文件复制的换行问题

使用 readLine() 读取时,会自动去掉换行符,因此写入时必须调用 newLine() 补充换行符,否则复制后的文件会变成一行。


六、完整工具类封装

可以把两种复制方式封装成通用工具类,直接调用即可:

import java.io.*;

public class FileCopyUtils {
    // 文本文件复制(字符缓冲流)
    public static void copyTextFile(String srcPath, String destPath) throws IOException {
        try (BufferedReader br = new BufferedReader(new FileReader(srcPath));
             BufferedWriter bw = new BufferedWriter(new FileWriter(destPath))) {
            String line;
            while ((line = br.readLine()) != null) {
                bw.write(line);
                bw.newLine();
            }
        }
    }

    // 任意文件复制(字节缓冲流)
    public static void copyAnyFile(String srcPath, String destPath) throws IOException {
        byte[] buffer = new byte[8192];
        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcPath));
             BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destPath))) {
            int len;
            while ((len = bis.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }
        }
    }

    // 测试
    public static void main(String[] args) throws IOException {
        // 复制文本文件
        copyTextFile("src/original.txt", "src/copy_text.txt");
        // 复制图片文件
        copyAnyFile("src/original.jpg", "src/copy_image.jpg");
    }
}

七、总结

  • 文本文件复制优先用字符缓冲流,便捷高效;
  • 任意文件复制必须用字节缓冲流,通用性强;
  • 缓冲流是 Java IO 性能优化的关键,必须掌握;
  • try-with-resources 是 Java IO 编程的规范写法,能避免资源泄漏。

更多推荐