🎋java文件与IO操作知识全景图(清晰框架)

在这里插入图片描述


🎋建议学习路线:

在这里插入图片描述


📌第1层:文件本身的操作——File类or Path(NIO.2)

目标: 管理文件或目录的存在性(创建、删除、判断是否存在等)。

✅ 常用类:
java.io.File(老式):exist(), createNNewFile(), delete()
java.nio.file.Path + Files(现代,推荐)

📌第2层:数据流动——基础流(InputStream/OutputStream, Reader/Writer)

目标: 读取或写入数据。
核心分类:

类型 用途 典型类
字节流 处理所有类型文件(图片、音频、文本) FileInputStream , FileOutputStream
字符流 专门处理文本,避免乱码 FileReader, FileWriter

特点:

  • 每次读一个字节或字符
  • 效率低(频繁访问磁盘)

(隐藏层)第2.5层: 编码转换层
这个层的核心就是两个类:

作用
InputStreamReader 字节输入流 → 字符输入流
OutputStreamWriter 字节输出流 → 字符输出流

📌第3层:提升效率——缓冲流(Buffered Streams)

目标: 减少I/O次数,提高性能。
典型包装:

BufferedReader br = new BufferedReader(
    new FileReader("file.txt")
);
  • 它内部有一个“缓冲区”,一次性读一大块数据存到内存
  • 你调用 readLine() 时,是从内存拿,不是每次都去磁盘读
  • 必须掌握!

📌第4层:现代方式——NIO.2 ( java 7+ )

目标: 更简洁、更强大、更安全
核心类:

  • Path :表示路径(比File更灵活)
  • Files :提供静态方法,一行搞定常见操作

示例:

// 复制文件(一行)
Files.copy(srcPath, destPath);

// 读取所有行
List<String> lines = Files.readAllLines(path);

// 写入所有行
Files.write(path, List.of("hello", "world"));

🍸实用建议:什么时候用什么?

你要做什么 推荐方式
创建空文件 file.createNewFile() 或 Files.createFile()
写文本内容 FileWriter + BufferedWriter
读文本内容 FileReader + BufferedReader
复制文本文件 BufferedReader → BufferedWriter
复制任意文件(如图片) FileInputStream → FileOutputStream(或 Files.copy())
避免乱码 使用 InputStreamReader 指定编码(如 UTF-8)
简化代码 学习 Files.readAllLines() / Files.write()

🍸题目练习

题目 1:【基础】复制文本文件(字符流 + 缓冲流)

要求:
编写程序,将 src.txt 文件的内容复制到 dest.txt 中。

关键知识点:

  • FileReader + FileWriter
  • BufferedReader 和 BufferedWriter
  • readLine() 方法
  • try-with-resources 自动关闭资源
import java.io.*;

public class Test1 {
    public static void main(String[] args) {
        String inp = "hello, java";
        //第一步:先创建 src.txt 并写入内容
        try (FileWriter f1 = new FileWriter("src.txt")) {
            f1.write(inp);
            System.out.println("源文件 src.txt 创建成功" );
        }catch(IOException e) {
            System.err.println("创建资源失败:"+e.getMessage());
            return; //!!!如果创建失败,不再运行以下代码
        }

        // 第二步:复制
        try(
                BufferedReader reader = new BufferedReader(new FileReader("src.txt"));
                BufferedWriter writer = new BufferedWriter(new FileWriter("dest.txt"));
        ){
              String line;
              while((line=reader.readLine())!=null) {
                  writer.write(line);
                  writer.newLine();
              }
              System.out.println("文件复制成功");
        }catch (FileNotFoundException e){
            System.err.println("文件未找到:"+ e.getMessage());
        } catch(IOException e){
            System.err.println("读写过程中出错:"+ e.getMessage());
        }
    }
}

题目 2:【编码处理】读取 GBK 编码的文件并输出

要求:
有一个 gbk_data.txt 文件,编码为 GBK,内容是中文。用 Java 正确读取并打印到控制台。

关键知识点:

  • InputStreamReader + FileInputStream
  • 指定编码 “GBK”
  • 避免乱码
import java.io.*;

public class Test2 {
    public static void main(String[] args) {
        String content = "今天你是否会想起……";
        //1-新建 gbk_data.txt 并以 GBK 编码写入内容
        try(OutputStreamWriter osw = new OutputStreamWriter(
                new FileOutputStream("gbk_data.txt"), "GBK");
            BufferedWriter bw = new BufferedWriter(osw)) {
            bw.write(content);
            System.out.println("源文件 src.txt 创建成功并写入数据" );
        }catch(IOException e){
            System.err.println("创建资源失败:"+e.getMessage());
            return; //!!!如果创建失败,不再运行以下代码
        }
        //2-以 GBK 编码读取文件
        try(InputStreamReader isr = new InputStreamReader(
                new FileInputStream("gbk_data.txt"),"GBK");
            BufferedReader br = new BufferedReader(isr);
        ){
            String line;
            while((line=br.readLine())!=null){
                System.out.println("读取内容"+line);

            }
            System.out.println("读取完成:");

        }catch (IOException e){
            System.err.println("打开资源失败:"+e.getMessage());
        }
    }
}

题目 3:【对象序列化】保存和读取学生对象

要求:
定义一个 Student 类,包含 name(String)、age(int),实现 Serializable 接口。
创建一个 Student 对象,使用 ObjectOutputStream 写入到 student.obj 文件。
再用 ObjectInputStream 读取该对象并打印。

关键知识点:

  • ObjectOutputStream / ObjectInputStream
  • Serializable 接口
  • transient 关键字(可选拓展)
import java.io.*;

public class Student implements Serializable {
    public int age;
    public String name;

    public static void main(String[] args) {
        Student obj=new Student();
        obj.age=15;
        obj.name="Alice";
        // 1-序列化对象——打开一个名为 object.ser 的文件,准备向其中写入原始字节数据。
        try(FileOutputStream fileOut = new FileOutputStream("object.ser");
            ObjectOutputStream out = new ObjectOutputStream(fileOut);
        ){
            // 将obj转化为字节序列
             out.writeObject(obj);
             System.out.println("对象已序列化并保存到object.ser");
        }catch (IOException e){
            System.err.println("序列化失败:" + e.getMessage());
            e.printStackTrace();
            return;
        }

        // 2-反序列化
        Student obj2=null;
        // 从文件读取原始字节;将原始字节还原为Java对象(若文件较大,可包装 BufferedInputStream 减少I/O次数)
        try(FileInputStream fileIn = new FileInputStream("object.ser");
            ObjectInputStream in = new ObjectInputStream(fileIn)){
            obj2 = (Student) in.readObject();
            // 输出
            System.out.println("name:"+obj2.name);
            System.out.println("age:"+obj2.age);
        } catch (IOException e){
            System.err.println("IO错误(文件读取失败):" + e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {   //!!!必须处理这个异常
            System.err.println("找不到Student类:" + e.getMessage());
            e.printStackTrace();
        }
    }
}

transient关键字:

  • 作用:被它修饰的字段,在对象序列化时不会被保存到文件中;
  • 只对字段有效,不能用于方法或局部变量;
  • static 字段本来就不会被序列化,加不加 transient 都一样;
  • 为什么需要它?
    在这里插入图片描述

题目 4:【综合】统计文件中单词数量

要求:
读取一个英文文本文件 words.txt,统计其中单词(以空格、换行、标点分隔)的总数。

关键知识点:

  • BufferedReader 逐行读取
  • String.split() 分词(正则:[\s\p{Punct}]+)
  • 累加统计

题目 5:【拓展】实现一个简单的“日志记录器”

要求:
写一个方法 log(String msg),每次调用时,将当前时间 + msg 写入 app.log 文件,追加模式。

关键知识点:

  • FileWriter 构造函数的 append 模式:new
  • FileWriter(“app.log”, true)
  • SimpleDateFormat 格式化时间
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐