FileOutputStream 详解与记忆方法
FileOutputStream 详解与记忆方法
一、FileOutputStream 核心概念
FileOutputStream
是 Java 中用于向文件写入原始字节的类,继承自 OutputStream
抽象类。
1. 核心特点
特性 | 说明 |
---|---|
继承关系 | OutputStream → FileOutputStream |
数据单位 | 字节(8bit) |
用途 | 写入二进制文件(如图片、音频等)或文本文件(需自行处理编码) |
是否缓冲 | 默认无缓冲(需配合 BufferedOutputStream 使用) |
线程安全 | 否 |
文件处理方式 | 默认覆盖文件,可通过构造方法选择追加模式 |
2. 构造方法
java
// 1. 通过文件路径创建(覆盖模式)
//创建一个文件字节输出流对象,这个流在使用的时候,最开始会将原文件内容全部清空,然后写入
FileOutputStream(String name);
FileOutputStream fos = new FileOutputStream("output.txt");
// 2. 追加模式写入
//创建一个文件字节输出流对象,当append是true的时候,不会清空原文件的内容,在源文件的末尾追加写入
FileOutputStream(String name,append);
FileOutputStream fos = new FileOutputStream("output.txt", true);
//创建一个文件字节输出流对象,当append是false的时候,会清空原文件的内容,然后写入
// 3. 通过File对象创建
File file = new File("output.txt");
FileOutputStream fos = new FileOutputStream(file);
// 4. 通过文件描述符创建(高级用法)
FileDescriptor fd = new FileDescriptor();
FileOutputStream fos = new FileOutputStream(fd);
3. 核心方法
方法 | 作用 |
---|---|
void write(int b) | 写入单个字节(低8位) |
void write(byte[] b) | 写入整个字节数组 |
void write(byte[] b, int off, int len) | 从数组的off 位置写入len 个字节(将byte字节数组的一部分写出) |
void close() | 关闭流 |
FileChannel getChannel() | 获取关联的FileChannel(NIO相关) |
void flush() | 强制将缓冲区内容写入磁盘(对无缓冲流无效) |
二、使用示例
1. 基础写入文件
java
try (FileOutputStream fos = new FileOutputStream("data.bin")) {
fos.write(65); // 写入ASCII 'A'
byte[] data = {66, 67, 68}; // B, C, D
fos.write(data);
}
2. 追加模式写入文本
java
String text = "Hello,世界!\n";
try (FileOutputStream fos = new FileOutputStream("log.txt", true)) { // 追加模式
fos.write(text.getBytes(StandardCharsets.UTF_8)); // 需指定编码
}
3. 高效写入(缓冲流)
java
try (FileOutputStream fos = new FileOutputStream("largefile.bin");
BufferedOutputStream bos = new BufferedOutputStream(fos)) { // 添加缓冲
byte[] data = new byte[1024];
// ...填充data...
bos.write(data); // 批量写入更高效
}
三、记忆技巧
1. 名称解析法
"File + Output + Stream"
File:操作文件
Output:输出(写入)
Stream:字节流
2. 对比记忆法
对比类 | 方向 | 数据单位 | 典型用途 |
---|---|---|---|
FileOutputStream | 写入 | 字节 | 图片、日志等任意文件 |
FileInputStream | 读取 | 字节 | 文件读取 |
FileWriter | 写入 | 字符 | 文本文件(自动处理编码) |
3. 使用场景联想
-
文件下载:
FileOutputStream
+ 网络流 -
数据备份:序列化对象写入文件
-
日志记录:追加模式写入日志文件
4. 常见误区提醒
❌ 错误用法:直接写入字符串(未处理编码)
✅ 正确做法:
java
String text = "中文内容";
fos.write(text.getBytes("UTF-8")); // 明确指定编码
四、面试高频问题
1. 如何实现文件追加写入?
java
// 第二个参数true表示追加模式
new FileOutputStream("log.txt", true);
2. write(int b) 为什么参数是int而非byte?
-
历史原因:早期Java的byte是无符号的(0-255),int可兼容所有byte值
-
实际处理:只写入int的低8位,其他位被忽略
3. 不调用close()会怎样?
-
资源泄漏:文件句柄未被释放,可能导致后续无法操作该文件
-
数据丢失:缓冲流中的数据可能未写入磁盘
4. 与BufferedOutputStream配合使用的优势?
-
减少IO次数:默认每次write()都会触发磁盘操作,缓冲流攒够数据后批量写入
-
性能提升:对小文件无感,大文件写入速度可提升10倍+
五、总结图示
mermaid
flowchart TD A[FileOutputStream] --> B[写入二进制文件] A --> C[核心方法: write/flush/close] A --> D[需配合缓冲流提升性能] B --> E[图片/日志/下载文件等] D --> F[BufferedOutputStream]
一句话总结:
"FileOutputStream写字节,append参数控追加,缓冲流来提性能,文本编码要明确"