一文吃透Java IO流!从底层原理到实战代码(新手必看)
前言但凡学 JavaIO 流是绕不开的核心基础无论是日常开发中的文件读写、日志记录、图片上传下载还是网络通信、数据持久化底层全部依赖 IO 流实现。同时它也是Java 面试高频考点、期末必考知识点。很多初学者学 IO 流都会陷入误区类太多、名字太像、不知道该用哪一个、代码写完总是乱码 / 报错。今天这篇博客我用最通俗的语言 分类梳理 可直接运行的实战代码带你从零吃透 Java IO 基础流看完直接告别 IO 流混乱一、什么是 IO 流核心本质1. IO 含义- IInput 输入读取数据数据从「外部设备」流向「Java 程序」例读取电脑本地文件内容到程序中- OOutput 输出写入数据数据从「Java 程序」流向「外部设备」例把程序中的文字、数据保存到本地文件2. 流的本质流就是数据传输的通道像水管一样数据以字节 / 字符的形式有序、单向、逐次传输。IO 流的核心特点单向传输、顺序读写、用完必关闭。二、IO 流核心分类重中之重Java IO 流体系庞大但所有流的顶层父类只有四个记住这四个类就掌握了 80% 的 IO 基础1. 按数据类型分类最核心区分1字节流Byte- 操作单位1 个字节8 位- 支持文件所有文件文本、图片、视频、音频、压缩包等- 适用场景文件复制、传输所有类型文件- 顶层父类- 输入InputStream抽象类- 输出OutputStream抽象类2字符流Char- 操作单位1 个字符中文 2 字节、英文 1 字节自动适配编码- 支持文件仅纯文本文件txt、java、md 等- 适用场景读写文本内容彻底解决中文乱码- 顶层父类- 输入Reader抽象类- 输出Writer抽象类2. 按传输方向分类- 输入流读数据外部 → 程序- 输出流写数据程序 → 外部3. 极简选择口诀新手直接背1. 图片 / 视频 / 文件复制 → 无脑用字节流2. 读写纯文本、处理中文 → 无脑用字符流三、四大基础流实战最常用所有 IO 资源属于系统资源Java 垃圾回收无法自动释放必须手动关闭推荐使用 try-with-resources 语法自动关闭流简洁且安全。1. 字节输入流 FileInputStream读文件作用读取任意类型文件的字节数据import java.io.FileInputStream;import java.io.IOException;/*** 字节输入流读取文件支持所有文件类型*/public class FileInputStreamDemo {public static void main(String[] args) {// try-with-resources自动关闭流try (FileInputStream fis new FileInputStream(test.txt)) {// 定义字节数组缓冲区一次读取1024字节效率更高byte[] buf new byte[1024];int len; // 记录本次读取的字节数// 循环读取len-1 表示读取完毕while ((len fis.read(buf)) ! -1) {// 字节数组转字符串输出读取内容String content new String(buf, 0, len);System.out.print(content);}} catch (IOException e) {e.printStackTrace();}}}2. 字节输出流 FileOutputStream写文件作用向文件写入字节数据支持覆盖 / 追加写入import java.io.FileOutputStream;import java.io.IOException;/*** 字节输出流写入文件* 第二个参数true追加写入默认false覆盖写入*/public class FileOutputStreamDemo {public static void main(String[] args) {try (FileOutputStream fos new FileOutputStream(test.txt, true)) {// 写入字符串转字节数组String str \nJava IO流实战测试;fos.write(str.getBytes());System.out.println(数据写入成功);} catch (IOException e) {e.printStackTrace();}}}3. 字符输入流 FileReader读文本专门优化文本读取自动处理字符编码中文无乱码import java.io.FileReader;import java.io.IOException;/*** 字符输入流只读纯文本文件*/public class FileReaderDemo {public static void main(String[] args) {try (FileReader fr new FileReader(test.txt)) {// 字符缓冲区char[] chars new char[1024];int len;while ((len fr.read(chars)) ! -1) {System.out.print(new String(chars, 0, len));}} catch (IOException e) {e.printStackTrace();}}}4. 字符输出流 FileWriter写文本专门用于文本写入操作更简洁import java.io.FileWriter;import java.io.IOException;/*** 字符输出流只写纯文本文件*/public class FileWriterDemo {public static void main(String[] args) {try (FileWriter fw new FileWriter(test.txt, true)) {// 直接写入字符串无需转字节fw.write(\n字符流写入中文测试无乱码);// 刷新缓冲区字符流必须刷新否则数据滞留缓冲区fw.flush();System.out.println(文本写入成功);} catch (IOException e) {e.printStackTrace();}}}四、高效缓冲流开发首选基础流是单字节 / 单字符读写频繁 IO 操作效率极低缓冲流自带内置缓冲区批量读写数据效率提升数十倍实际开发一律用缓冲流。缓冲流对应四类1. 字节缓冲BufferedInputStream / BufferedOutputStream2. 字符缓冲BufferedReader / BufferedWriter核心优势- 减少磁盘 IO 次数性能极高- 字符缓冲流独有readLine () 逐行读取、newLine() 换行极度方便实战字符缓冲流读写文本最常用import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;/*** 缓冲流实战高效读写文本*/public class BufferedIODemo {public static void main(String[] args) {// 写入数据try (BufferedWriter bw new BufferedWriter(new FileWriter(bufferTest.txt))) {bw.write(Java IO缓冲流测试);bw.newLine(); // 自动换行跨平台兼容bw.write(高效读写开发首选);bw.flush();} catch (IOException e) {e.printStackTrace();}// 读取数据逐行读取try (BufferedReader br new BufferedReader(new FileReader(bufferTest.txt))) {String line;// 逐行读取null表示读取完毕while ((line br.readLine()) ! null) {System.out.println(line);}} catch (IOException e) {e.printStackTrace();}}}五、转换流解决乱码终极方案痛点FileReader/FileWriter 默认跟随系统编码Windows 默认 GBKIDEA 默认 UTF-8极易出现中文乱码核心作用字节流 → 字符流并手动指定编码格式UTF-8/GBK彻底解决乱码问题两个核心类1. InputStreamReader字节输入流转字符输入流指定编码读2. OutputStreamWriter字节输出流转字符输出流指定编码写编码统一实战import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.IOException;/*** 转换流指定UTF-8编码彻底解决乱码*/public class ConvertIODemo {public static void main(String[] args) {// 以UTF-8编码读取文件try (BufferedReader br new BufferedReader(new InputStreamReader(new FileInputStream(test.txt), UTF-8))) {// 以UTF-8编码写入文件try (BufferedWriter bw new BufferedWriter(new OutputStreamWriter(new FileOutputStream(utf8_test.txt), UTF-8))) {String line;while ((line br.readLine()) ! null) {bw.write(line);bw.newLine();}System.out.println(编码统一复制完成无乱码);}} catch (IOException e) {e.printStackTrace();}}}六、IO 流高频必备文件复制通用工具结合字节缓冲流实现任意文件无损复制图片、视频、文本通用开发高频工具方法import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;/*** 通用文件复制工具类支持所有文件类型*/public class FileCopyUtil {public static void main(String[] args) {// 源文件路径、目标文件路径copyFile(source.jpg, target.jpg);System.out.println(文件复制成功);}/*** 文件复制通用方法* param srcPath 源文件路径* param destPath 目标文件路径*/public static void copyFile(String srcPath, String destPath) {try (BufferedInputStream bis new BufferedInputStream(new FileInputStream(srcPath));BufferedOutputStream bos new BufferedOutputStream(new FileOutputStream(destPath))) {byte[] buf new byte[1024 * 8]; // 8KB缓冲区int len;while ((len bis.read(buf)) ! -1) {bos.write(buf, 0, len);}bos.flush(); // 刷新缓冲区} catch (IOException e) {e.printStackTrace();}}}七、新手常见坑 避坑总结1. 流必须关闭 / 刷新- 字符流不 flush ()、不 close () → 数据滞留缓冲区写入失效- 不关闭流 → 造成资源泄露占用系统资源2. 乱码问题解决方案- 不要用默认字符流读写不同编码文件一律用转换流指定 UTF-83. 流选择禁忌- 图片、视频禁止使用字符流会导致文件损坏、无法打开4. 性能禁忌- 禁止使用基础单字节读写开发一律用缓冲流效率差距极大八、IO 流体系思维导图总结IO流├─ 按数据类型│ ├─ 字节流所有文件InputStream / OutputStream│ └─ 字符流纯文本Reader / Writer├─ 基础节点流│ ├─ FileInputStream / FileOutputStream字节文件读写│ └─ FileReader / FileWriter文本读写├─ 高效缓冲流开发首选│ └─ BufferedXXX自带缓冲区批量读写└─ 转换流编码处理└─ InputStreamReader / OutputStreamWriter统一编码解决乱码结尾IO 流是 Java文件操作、框架底层、网络编程的基石没有复杂逻辑核心就是分清流的用途、规范关闭资源、优先使用缓冲流。