15、Java 基础硬核复习:File类与IO流的核心逻辑与面试考点

15、Java 基础硬核复习:File类与IO流的核心逻辑与面试考点

在Java开发中,File类与IO流是连接程序与外部世界(文件、网络)的核心工具。即使现在有Spring等框架封装了IO操作,底层的流(Stream)概念和序列化机制依然是面试中的必考基础。本章逻辑清晰:先操作"文件本身"(File类),再操作"文件内容"(IO流)。

一、核心知识体系

1. File类:操作文件的"元数据"

java.io.File是文件或目录路径的抽象表示,只能操作文件的元数据 (如创建、删除、重命名、获取大小),不能修改文件内容

  • 路径问题
    • 绝对路径:从盘符(Windows)或根目录(Linux)开始的完整路径(如D:/a.txt);
    • 相对路径:相对于当前项目目录的路径(如src/a.txt),跨平台需用File.separator(如/\)。
  • 常用方法
    • 判断:exists()(是否存在)、isFile()(是否为文件)、isDirectory()(是否为目录);
    • 创建:createNewFile()(创建文件)、mkdir()(创建单级目录)、mkdirs()(创建多级目录);
    • 删除:delete()(删除文件/空目录,非空目录需先删文件);
    • 遍历:listFiles()(返回File对象数组,可结合递归遍历所有子目录和文件)。

2. IO流的分类与体系(重点)

IO流是数据传输的通道,分类依据如下:

  • 按数据单位
    • 字节流(Byte Stream):InputStream/OutputStream,操作8-bit,适合所有文件(图片、视频、音频);
    • 字符流(Character Stream):Reader/Writer,操作16-bit,只适合纯文本文件(如.txt、.java)。
  • 按流的角色
    • 节点流:直接作用于数据源(如FileInputStream读取文件);
    • 处理流:包在节点流外面,增强功能(如BufferedInputStream提供缓冲,ObjectInputStream实现序列化)。
  • 四大核心抽象基类
    所有流都继承自InputStream(字节输入流)、OutputStream(字节输出流)、Reader(字符输入流)、Writer(字符输出流)。

3. 重要流的实战

(1)文件流:操作文件内容
  • 字节流:FileInputStream(读二进制文件)、FileOutputStream(写二进制文件);
  • 字符流:FileReader(读文本文件)、FileWriter(写文本文件)。
(2)缓冲流:提升IO效率的"加速器"

缓冲流内部维护一个缓冲区(默认8KB),减少磁盘IO次数(批量读写),显著提升大文件处理速度。

  • 字节缓冲流:BufferedInputStream(读)、BufferedOutputStream(写);
  • 字符缓冲流:BufferedReader(读,提供readLine()方法)、BufferedWriter(写,提供newLine()方法)。
(3)转换流:解决"乱码"的关键

转换流是字节流与字符流的桥梁,核心功能是处理编码与解码(解决乱码问题)。

  • InputStreamReader:字节输入流 → 字符输入流(需指定编码,如new InputStreamReader(new FileInputStream("a.txt"), "GBK"));
  • OutputStreamWriter:字符输出流 → 字节输出流(同理,指定编码)。
(4)对象流:实现序列化与反序列化

对象流用于将Java对象转换为二进制流(持久化存储或网络传输)。

  • 序列化:ObjectOutputStream(将对象写入文件);
  • 反序列化:ObjectInputStream(将文件中的二进制流还原为对象);
  • 注意:类需实现Serializable接口(标记接口,无方法),serialVersionUID用于版本控制(反序列化时校验)。

二、高频面试考点(必须掌握)

1. 字节流 vs 字符流(🌟必考Top 1)

  • 区别
    • 字节流按8-bit传输,不处理编码;字符流按16-bit传输,内部根据编码表将字节转换为字符。
  • 选择
    • 纯文本文件(.txt、.java)→ 字符流;
    • 二进制文件(图片、视频、音频)→ 字节流(图片不能用字符流,二进制数据无法在编码表中找到对应字符,会导致数据损坏)。

2. read() vs read(byte[]/char[] buffer)(性能差异)

  • read():每次只读1个字节/字符,频繁操作磁盘,效率极低(类似"用勺子舀水");
  • read(buffer):每次读取一个数组的数据(如1024个),批量读写,效率高(类似"用铲子铲水")。

3. 序列化机制(Serialization)

  • 定义:将内存中的Java对象转换为二进制流(持久化存储或网络传输);
  • Serializable接口:标记接口,告诉JVM该类允许被序列化;
  • serialVersionUID :版本控制,序列化后修改类代码(未改ID)会导致反序列化失败(抛InvalidClassException)。

4. transient关键字(不想序列化的属性)

  • 作用:修饰属性(如密码、银行卡号),序列化时忽略该属性,反序列化时该值为默认值(null或0)。

5. 乱码问题(Encoding)

  • 原因:编码与解码使用的字符集不一致(如文件用UTF-8存,用GBK读);
  • 解决 :使用转换流(InputStreamReader),并在构造器中显式指定正确编码(如new InputStreamReader(new FileInputStream("a.txt"), "GBK"))。

6. close()flush()(资源释放)

  • close():自动调用flush()刷新缓冲区(将缓冲区数据写入文件),并释放系统资源(如文件句柄);
  • 不关闭的后果:文件被占用无法删除,或缓冲区数据丢失。
  • 现代Java开发推荐try-with-resources自动关闭流(如try (FileInputStream fis = new FileInputStream("a.txt")) {})。

三、学习建议

  1. 实操对比 :写一个"文件复制"工具,分别用字节流(FileInputStream+FileOutputStream)和缓冲流(BufferedInputStream+BufferedOutputStream)复制100MB视频,对比耗时(缓冲流效率更高);
  2. 乱码修复 :故意用错误编码读取文本文件(如GBK文件用UTF-8读),观察乱码,再用转换流修复(指定正确编码),这是解决生产环境Bug的基本功。
    掌握本章核心知识,不仅能应对面试,更能理解Java与外部交互的本质,为后续学习NIO、网络编程打下基础。
相关推荐
Mr YiRan10 小时前
C++面向对象继承与操作符重载
开发语言·c++·算法
Drifter_yh12 小时前
【黑马点评】Redisson 分布式锁核心原理剖析
java·数据库·redis·分布式·spring·缓存
一只鹿鹿鹿12 小时前
智慧水利一体化建设方案
大数据·运维·开发语言·数据库·物联网
莫寒清13 小时前
Spring MVC:@RequestParam 注解详解
java·spring·mvc
香芋Yu14 小时前
【大模型面试突击】10_推理部署与优化
面试·职场和发展
没有医保李先生14 小时前
字节对齐的总结
java·开发语言
Elastic 中国社区官方博客14 小时前
使用 Elastic 进行网络监控:统一网络可观测性
大数据·开发语言·网络·人工智能·elasticsearch·搜索引擎·全文检索
Codefengfeng14 小时前
Python Base环境中加包的方法
开发语言·python
清水白石00814 小时前
《Python 编程全景解析:从核心精要到测试替身(Test Doubles)五大武器的实战淬炼》
开发语言·python
八月的冰可乐14 小时前
【无标题】
ai·面试