Java IO库
Java IO(Input/Output)库是 Java 提供的用于处理输入输出操作的 API 集合,主要用于在程序与外部设备(如文件、网络、键盘、显示器等)之间进行数据传输。
Java IO 库的核心主要分为以下几类:
字节流(Byte Streams)
以字节为单位处理数据,适用于所有类型的文件(包括二进制文件)
基类:InputStream(输入)和OutputStream(输出)
常用实现类:
FileInputStream/FileOutputStream:文件读写
BufferedInputStream/BufferedOutputStream:带缓冲的流,提高效率
ByteArrayInputStream/ByteArrayOutputStream:内存中的字节数组流
在 Java IO 中,BufferedInputStream/BufferedOutputStream和ByteArrayInputStream/ByteArrayOutputStream是字节流的重要实现类,它们的设计目的和使用场景各有不同:
1. BufferedInputStream/BufferedOutputStream(带缓冲的流)
核心作用:通过缓冲区减少 IO 操作次数,提高读写效率。
工作原理:
普通的字节流(如FileInputStream)每次读写数据都会直接操作底层设备(如硬盘),而 IO 操作是非常耗时的。
缓冲流会在内存中创建一个缓冲区(默认 8KB),读写数据时先在缓冲区中操作:
读取时,一次性从底层设备读取一批数据到缓冲区,后续读取直接从缓冲区获取
写入时,先将数据累积到缓冲区,当缓冲区满了再一次性写入到底层设备
示例代码:
// 使用缓冲流读取文件(效率更高)
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("data.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.txt"))) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = bis.read(buffer)) != -1) {
bos.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
}
适用场景:
对文件、网络流等底层设备进行读写时使用
任何需要提高 IO 效率的场景(几乎所有字节流操作都推荐配合缓冲流使用)
2. ByteArrayInputStream/ByteArrayOutputStream(字节数组流)
核心作用:在内存中以字节数组为载体进行 IO 操作,相当于 "内存中的文件流"。
字节数组:
字节数组(Byte Array)是由多个字节(byte)组成的有序集合,是计算机中存储和处理二进制数据的基础结构之一。
在 Java 中,字节数组的特点和用途如下:
1. 基本特性
每个元素是 8 位(1 字节)的二进制数据,取值范围是 - 128 到 127
是一种固定长度的容器,创建后不能改变大小
直接存储原始二进制数据,没有编码转换开销
2. 声明与初始化
// 声明一个字节数组
byte[] byteArray1;
// 初始化方式1:指定长度
byte[] byteArray2 = new byte[10]; // 创建长度为10的字节数组
// 初始化方式2:直接指定元素
byte[] byteArray3 = {65, 66, 67, 68}; // 对应ASCII码的A、B、C、D
// 初始化方式3:通过字符串转换
byte[] byteArray4 = "Hello".getBytes(); // 将字符串按默认编码转为字节数组
3. 主要用途
IO 操作:字节流读写的核心数据载体(如文件、网络传输)
二进制数据处理:存储图片、音频、视频等二进制文件内容
数据转换:字符串与字节的相互转换(涉及字符编码)
内存缓存:在内存中临时存储数据(如 ByteArrayInputStream/ByteArrayOutputStream 的内部存储)
4. 与字符串的转换
// 字符串转字节数组
String str = "Hello World";
byte[] bytes = str.getBytes("UTF-8"); // 推荐指定编码
// 字节数组转字符串
String newStr = new String(bytes, "UTF-8"); // 使用相同编码转换回来
toByteArray()与getBytes()区别
toByteArray() 主要是 ByteArrayOutputStream 等流类 将流中累积的所有数据转换为字节数组
getBytes() String 类 将当前字符串按指定编码转换为字节数组
5. 为什么重要?
计算机底层所有数据最终都以二进制形式存储,字节数组是直接操作这些二进制数据的最基本方式。无论是文件读写、网络通信还是数据加密等场景,都需要通过字节数组来处理原始数据。
例如,当你读取一个图片文件时,文件内容会被读取为字节数组;发送网络请求时,请求数据也会被转换为字节数组进行传输。
工作原理:
ByteArrayInputStream:从一个字节数组中读取数据(把字节数组当作数据源)
ByteArrayOutputStream:把数据写入到内部维护的字节数组中(把字节数组当作目标容器)
示例代码:
// 内存中处理数据(无需操作文件)
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
// 向内存中的字节数组写入数据
String data = "Hello, ByteArrayStream!";
baos.write(data.getBytes());
// 获取写入的字节数组
byte[] result = baos.toByteArray();
System.out.println(new String(result)); // 输出写入的数据
// 从字节数组读取数据
try (ByteArrayInputStream bais = new ByteArrayInputStream(result)) {
byte[] buffer = new byte[1024];
int bytesRead = bais.read(buffer);
System.out.println(new String(buffer, 0, bytesRead)); // 再次输出数据
}
} catch (IOException e) {
e.printStackTrace();
}
适用场景:
需要在内存中临时存储或处理字节数据(如数据转换、压缩解压、网络数据暂存)
避免频繁创建临时文件的场景(纯内存操作,速度快)
模拟文件操作进行测试(无需真实文件系统)
总结区别
类型 数据来源 / 目标 核心优势 典型用途
缓冲流 底层设备(文件 / 网络等) 减少 IO 次数,提高效率 文件读写、网络传输
字节数组流 内存中的字节数组 纯内存操作,速度快 内存数据处理、临时缓存
两者可以结合使用,例如:用ByteArrayOutputStream在内存中生成数据,再通过BufferedOutputStream写入文件,兼顾内存操作的灵活性和文件写入的效率。
字符流(Character Streams)
以字符为单位处理数据,适用于文本文件
基类:Reader(输入)和Writer(输出)
常用实现类:
FileReader/FileWriter:文本文件读写
BufferedReader/BufferedWriter:带缓冲的字符流
InputStreamReader/OutputStreamWriter:字节流与字符流的转换(处理编码)
NIO(New IO)
Java 1.4 引入的新 IO 模型,基于缓冲区(Buffer)和通道(Channel)
支持非阻塞 IO 操作,更适合高并发场景
核心组件:Buffer、Channel、Selector、Charset等
其他常用类
File:文件和目录操作
RandomAccessFile:支持随机访问文件
PrintStream/PrintWriter:格式化输出
基本使用示例(文件读写):
// 字节流读取文件
try (InputStream is = new FileInputStream("file.txt");
OutputStream os = new FileOutputStream("copy.txt")) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
}
// 字符流读取文本
try (BufferedReader br = new BufferedReader(new FileReader("text.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
Java 7 之后引入的 try-with-resources 语法可以自动关闭流资源,推荐使用以避免资源泄漏。
在选择 IO 流时,基本原则是:处理文本文件优先使用字符流,处理二进制文件使用字节流,需要高效处理或非阻塞操作时考虑 NIO。
更多推荐



所有评论(0)