IO流知识点

一、核心概念

1. 流(Stream)

流是 Java IO 的核心抽象,代表数据的流动方向,可以理解为 "数据管道":

  • 输入流(Input Stream):从外部(文件、网络、键盘)读取数据到程序中
  • 输出流(Output Stream):将程序中的数据写入到外部(文件、网络、控制台)
  • 流的特性:单向流动 (输入只能读,输出只能写)、顺序访问(从头读到尾,不能随机跳转)

2. 分类方式

Java IO 流有多种分类维度,新手需重点掌握:

表格

分类维度 具体类型 核心抽象类 适用场景
数据方向 输入流 / 输出流 InputStream/OutputStream 读数据 / 写数据
数据类型 字节流 / 字符流 字节流:同上字符流:Reader/Writer 字节流:任意数据(图片、视频、二进制文件)字符流:文本数据(txt、Java 文件)
功能扩展 节点流 / 处理流 节点流:FileInputStream处理流:BufferedInputStream 节点流:直接操作数据源处理流:包装节点流,增强功能(缓冲、编码转换)

二、核心流体系(常用实现类)

1. 字节流(处理所有类型数据)

(1)节点流(直接操作文件)
  • FileInputStream:读取文件字节数据
  • FileOutputStream:写入文件字节数据

示例:字节流读写文件

java

运行

复制代码
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class ByteStreamDemo {
    public static void main(String[] args) {
        // 1. 定义源文件和目标文件路径
        String sourcePath = "source.txt";
        String targetPath = "target.txt";
        
        // 2. 声明流对象(try-with-resources 自动关闭流,推荐用法)
        try (FileInputStream fis = new FileInputStream(sourcePath);
             FileOutputStream fos = new FileOutputStream(targetPath)) {
            
            // 3. 定义缓冲区(减少IO次数,提升效率)
            byte[] buffer = new byte[1024];
            int len; // 记录每次读取的字节数
            
            // 4. 循环读取并写入
            while ((len = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, len); // 只写入实际读取的字节数
            }
            System.out.println("文件复制完成");
            
        } catch (IOException e) {
            e.printStackTrace(); // 异常处理
        }
    }
}
(2)处理流(增强功能)
  • BufferedInputStream/BufferedOutputStream:缓冲流,减少磁盘 IO 次数(核心优化)
  • DataInputStream/DataOutputStream:数据流,支持读写基本数据类型(int、double 等)

示例:缓冲流优化文件读写

java

运行

复制代码
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class BufferedStreamDemo {
    public static void main(String[] args) {
        String sourcePath = "large_file.zip";
        String targetPath = "copy_large_file.zip";
        
        // 包装节点流为缓冲流(缓冲区默认8KB)
        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourcePath));
             BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(targetPath))) {
            
            byte[] buffer = new byte[4096]; // 4KB缓冲区
            int len;
            while ((len = bis.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }
            // 缓冲流需手动刷新(或关闭时自动刷新)
            bos.flush();
            System.out.println("大文件复制完成(缓冲流优化)");
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2. 字符流(处理文本数据)

字符流基于字节流封装,自动处理编码问题(如 UTF-8、GBK),避免中文乱码。

核心实现类
  • FileReader/FileWriter:字符节点流,读写文本文件
  • BufferedReader/BufferedWriter :字符缓冲流,支持按行读写(readLine()/newLine())
  • InputStreamReader/OutputStreamWriter:转换流,实现字节流→字符流的转换(指定编码)

示例:字符缓冲流按行读写文本

java

运行

复制代码
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CharStreamDemo {
    public static void main(String[] args) {
        String sourcePath = "text.txt";
        String targetPath = "copy_text.txt";
        
        try (BufferedReader br = new BufferedReader(new FileReader(sourcePath));
             BufferedWriter bw = new BufferedWriter(new FileWriter(targetPath))) {
            
            String line;
            // 按行读取文本(readLine()返回null表示读取结束)
            while ((line = br.readLine()) != null) {
                bw.write(line); // 写入一行
                bw.newLine();   // 写入换行符(跨平台兼容)
            }
            System.out.println("文本文件复制完成(按行读写)");
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

示例:转换流指定编码读写

java

运行

复制代码
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class ConvertStreamDemo {
    public static void main(String[] args) {
        // 读取GBK编码的文本文件,避免乱码
        try (InputStreamReader isr = new InputStreamReader(new FileInputStream("gbk_file.txt"), "GBK");
             BufferedReader br = new BufferedReader(isr)) {
            
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println("GBK编码内容:" + line);
            }
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

三、NIO 简介(补充知识点)

Java 1.4 引入 NIO(New IO),解决传统 IO 的性能问题,核心差异:

  • 传统 IO:阻塞式、面向流(Stream)
  • NIO:非阻塞式、面向缓冲区(Buffer)、支持通道(Channel)和选择器(Selector)
  • 适用场景:高并发网络编程(如服务器开发),文件读写仍可使用传统 IO(简单易用)

四、最佳实践

  1. 关闭流 :使用try-with-resources(Java 7+)自动关闭流,避免资源泄漏
  2. 缓冲流优化:读写文件时优先使用缓冲流(BufferedXXX),减少磁盘 IO
  3. 编码统一:处理文本时指定编码(如 UTF-8),避免乱码
  4. 异常处理:捕获 IO 异常并处理(如打印日志、提示用户)
  5. 大文件处理:使用缓冲区分批次读写,避免一次性加载整个文件到内存

总结

  1. 核心分类:Java IO 分为字节流(处理所有数据)和字符流(处理文本,解决编码),节点流直接操作数据源,处理流增强功能(如缓冲)。
  2. 关键优化:读写文件时优先使用缓冲流(BufferedInputStream/BufferedReader),减少 IO 次数提升效率。
  3. 最佳实践 :使用try-with-resources自动关闭流,处理文本时指定编码,避免资源泄漏和乱码问题。
相关推荐
Wang's Blog13 分钟前
Java 项目实战: 交友项目 - 查询单条动态:动态详情页的接口与实现
java·开发语言·交友
yuniko-n14 分钟前
【JUC】CAS
java·开发语言
紧跟先前的步伐17 分钟前
Go AI Agent 实战 17|模型适配层设计:让模型可替换
开发语言·人工智能·后端·ai·golang
小灰灰搞电子28 分钟前
Qt 中使用 QSettings 存储结构体数据详解
开发语言·qt
计算机毕业编程指导师32 分钟前
基于深度学习的电子垃圾与混合材料图像分类系统实战:ResNet-50迁移学习+Django部署+三种识别入口完整方案
python·深度学习·毕业设计·resnet·课程设计·图像分类·电子垃圾
外收内放33 分钟前
FastAPI猜字谜实战(5):会话管理
开发语言·python·学习·fastapi
Ai-_Man34 分钟前
Microsoft Copilot对话数据怎么导入到另外一个Microsoft Copilot账号里去?AI导出鸭
开发语言·javascript·人工智能·microsoft·chatgpt·ecmascript·copilot
垆边人似月.37 分钟前
选型与快速跑通(Tesseract / EasyOCR / PaddleOCR)
前端·python
H.莓飛39 分钟前
【数据结构】归并与外排序
linux·服务器·c语言·开发语言·数据结构·visual studio
技术老孙41 分钟前
给 Agent 装上对话框 —— AgentScope-Java 接入 Spring Boot 与 SSE 流式实战
java·开发语言·spring boot