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、网络编程打下基础。
相关推荐
泡干脆面就番茄5 分钟前
HDFS读写流程与MapReduce原理深度解析(面试高频考点)
hdfs·面试·mapreduce
Nebula_g8 分钟前
JavaSE项目实践:红包雨-线程池/线程
java·开发语言
外收内放9 分钟前
Python基础语法练习题(56优化版补充)
开发语言·python
小羊没烦恼!9 分钟前
jQuery1.5的改进细节
java·服务器·开发语言·前端·c#
霸道流氓气质12 分钟前
Prompt 版本控制与 A/B 测试实战:语义版本管理、一致性哈希分流与 Thompson Sampling 的 Java 生产级实现
java·prompt·哈希算法
bksczm17 分钟前
0基础面试3
面试·职场和发展
程序员老陆41 分钟前
C++ 未定义行为全景:对象模型、优化边界与工程防御
开发语言·c++·程序设计
嵌入式er1 小时前
影石系统组 一二面OC面经
java·开发语言
徐小黑ACG1 小时前
Golang 基础06 接口interface
开发语言·后端·golang
春涧草茶1 小时前
慢就是快12-12手动抛出异常
java·linux·前端