Java 中字节流的使用详解
前言
在 Java 的 I/O 操作中,字节流(Byte Stream) 是最基本的输入输出方式。它以字节为单位进行数据的读取和写入,适用于处理二进制文件(如图片、音频、视频等),也可以用来处理文本文件。Java 提供了丰富的字节流类来完成各种 I/O 操作。
本篇博客将详细介绍 Java 中常用的字节流类及其使用方法,并通过示例代码帮助理解其工作原理。
一、什么是字节流?
Java 的 java.io 包中定义了两种类型的流:
- 字节流(Byte Stream):以字节(8位)为单位处理数据。
- 字符流(Character Stream):以字符(16位 Unicode 字符)为单位处理数据。
字节流的抽象基类是:
- InputStream:用于从源读取字节。
- OutputStream:用于向目标写入字节。
常见的子类包括:
类名 | 描述 |
---|---|
FileInputStream | 从文件中读取字节 |
FileOutputStream | 向文件中写入字节 |
ByteArrayInputStream | 从字节数组中读取数据 |
ByteArrayOutputStream | 将数据写入字节数组 |
BufferedInputStream / BufferedOutputStream | 带缓冲功能的字节流,提高性能 |
二、基本使用示例
1. 使用 FileInputStream 和 FileOutputStream
这是最基础的文件复制操作,适用于所有类型的文件。
public class FileCopyExample {public static void main(String[] args) {String sourcePath = "source.jpg";String destPath = "destination.jpg";try (FileInputStream fis = new FileInputStream(sourcePath);FileOutputStream fos = new FileOutputStream(destPath)) {int byteRead;while ((byteRead = fis.read()) != -1) {fos.write(byteRead);}System.out.println("文件复制成功!");} catch (IOException e) {e.printStackTrace();}}
}
注意:
使用 try-with-resources 确保资源自动关闭。
read() 返回的是一个 int 类型,表示读取到的字节(0~255),若返回 -1 表示已到达文件末尾。
2. 使用缓冲提升性能 —— BufferedInputStream 和 BufferedOutputStream
对于大文件来说,逐字节读取效率较低。可以使用缓冲流一次性读取多个字节。
import java.io.*;public class BufferedFileCopy {public static void main(String[] args) {String sourcePath = "bigfile.mp4";String destPath = "copy_bigfile.mp4";try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourcePath));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destPath))) {byte[] buffer = new byte[1024]; // 缓冲区大小int bytesRead;while ((bytesRead = bis.read(buffer)) != -1) {bos.write(buffer, 0, bytesRead);}System.out.println("带缓冲的大文件复制完成!");} catch (IOException e) {e.printStackTrace();}}
}
使用缓冲区(buffer)可以显著提高 I/O 效率,建议每次读取 1KB~8KB 数据。
三、常见字节流类详解
1. ByteArrayInputStream 和 ByteArrayOutputStream
这两个类用于在内存中操作字节流,常用于临时存储或转换数据。
public class ByteArrayExample {public static void main(String[] args) throws IOException {String data = "Hello, Byte Stream!";byte[] bytes = data.getBytes();// 写入内存ByteArrayOutputStream baos = new ByteArrayOutputStream();baos.write(bytes);System.out.println("写入内存的数据: " + baos.toString());// 从内存读取ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());int c;while ((c = bais.read()) != -1) {System.out.print((char)c);}}
}
四、字节流 vs 字符流
对比项 | 字节流 | 字符流 |
---|---|---|
单位 | 字节(8位) | 字符(16位 Unicode) |
适用场景 | 二进制文件(图片、音频等) | 文本文件(txt、json 等) |
主要类 | InputStream / OutputStream | Reader / Writer |
是否编码无关 | 是 | 否,需指定编码格式 |
五、总结
字节流是 Java I/O 操作中最基础的部分,掌握其使用对于理解 Java 文件处理机制至关重要。以下是几个关键点:
- 使用 FileInputStream 和 FileOutputStream 进行文件读写;
- 使用缓冲流(BufferedInputStream / BufferedOutputStream)提高效率;
- 对于内存操作可使用 ByteArrayInputStream 和 ByteArrayOutputStream;
- 字节流适合处理二进制数据,字符流更适合处理文本。