# 2026年8月6日 课后作业 — File 文件操作 + IO 流入门:文件复制器 > **说明**:本次课程学习了 **文件操作类 File**(创建 / 删除 / 判断 / 获取)和 **IO 流入门**(字节流:`FileOutputStream` 输出、`FileInputStream` 输入、文件复制)。本作业只出 **1 道题——文件复制器**,要求用 `FileInputStream` + `FileOutputStream` 配合 `byte[]` 缓冲区完成文件的完整复制,并统计耗时。 > > 这道题覆盖:**字节输入流读取(read / read(byte[]) / -1 结束)**、**字节输出流写入(write / write(byte[],0,len))**、**缓冲区思想**、**流的关闭**、**IOException 处理**、**System.currentTimeMillis() 耗时统计** 等核心知识点。 --- ## 📌 作业总体要求 ### 一、命名要求 | 项目 | 要求 | |------|------| | **类名** | `Demo_01_你的姓名`(如 `Demo_01_张三`) | | **文件头注释** | 每个 Java 文件头部需包含 `@author`、`@title`、`@create` 文档注释 | ### 二、提交方式与截止时间 | 项目 | 要求 | |------|------| | **提交方式** | 将源码文件 + 运行结果截图提交至班级指定平台 | | **截止时间** | 下次上课前 | --- ## 一、作业题目(必做 · 共 1 题) ### 题目 1:文件复制器 FileCopy(⭐⭐⭐ 必做) **知识点**:`FileInputStream`(字节输入流读取)、`FileOutputStream`(字节输出流写入)、`read(byte[])` / `write(byte[], 0, len)`、缓冲区 `byte[4096]`、`-1` 文件末尾判断、`close()` 关闭流、`IOException`、`System.currentTimeMillis()` 耗时统计 **场景描述**:文件复制 = **输入流读 + 输出流写**:用 `FileInputStream` 把源文件的数据读到 `byte[]` 缓冲区,再用 `FileOutputStream` 把缓冲区内容写入目标文件,循环往复直到读完(`read` 返回 `-1`)。请实现一个**文件复制器**,把任意文件(如视频 .mp4)完整复制一份,并输出复制耗时。 **题目要求**: ```java import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; /** * @author 你的姓名 * @title 题目1:文件复制器 * @create 2026/8/6 */ public class Demo_01_姓名 { public static void main(String[] args) throws IOException { String src = "E:/授课资料/示例.mp4"; // 源文件路径(请替换成你本机的文件) String desc = "D:/示例_副本.mp4"; // 目标文件路径 long startTime = System.currentTimeMillis(); // 复制开始时刻(毫秒) // TODO 1: 创建输入流对象(FileInputStream 读源文件)和输出流对象(FileOutputStream 写目标文件) // TODO 2: 创建 byte[4096] 缓冲区; // 用 while 循环调用 fis.read(bytes),返回值是本次读到的有效字节长度, // 当返回 -1 表示读完结束循环;否则用 fos.write(bytes, 0, length) 写入本次有效字节 // TODO 3: 先关闭输出流,再关闭输入流 long endTime = System.currentTimeMillis(); // 复制结束时刻 System.out.println("复制完成!耗时:" + (endTime - startTime) + " 毫秒"); } } ``` **预期输出示例**: ``` 复制完成!耗时:312 毫秒 (目标路径下生成与源文件内容完全一致的副本文件) ``` **要求说明**: 1. 复制前后对比源文件与目标文件的大小,必须**完全一致**(可用文件属性查看) 2. 必须使用**缓冲区循环读取**(`while ((length = fis.read(bytes)) != -1)`),**不允许**用 `read()` 逐字节复制 3. `write` 必须使用 `write(bytes, 0, length)`,**只写入本次读到的有效字节数** **💡 提示**: - `fis.read(bytes)` 返回的是**本次读取的有效字节长度**,可能小于缓冲区大小(如最后一段数据),所以写入时务必用 `0, length` 截断,否则会把缓冲区残留数据一起写入导致文件变大 - 关闭顺序:先 `fos.close()` 再 `fis.close()` - 进阶思考:把 `byte[4096]` 改成 `byte[1024]` / `byte[8192]`,复制耗时有何变化?(缓冲区越大单次读写越高效,但过大会浪费内存) **🎯 挑战加分(选做)**: 1. 用 `try-catch-finally` 保证无论是否发生异常都能关闭流(`finally` 中 `close()`) 2. 用 `Scanner` 让用户从键盘输入源文件路径和目标文件路径 3. 对比缓冲区大小 `1024` / `4096` / `8192` 三种情况下的复制耗时并输出 --- ## 四、提交要求 - **类名**:`Demo_01_姓名`(如 `Demo_01_张三`) - **文件头注释**:每个 Java 文件头部必须包含 `@author`(你的姓名)、`@title`(题目名称)、`@create 2026/8/6` - 提交内容:源码文件 + 运行结果截图