FileInputStream 详解与记忆方法
一、FileInputStream 核心概念
FileInputStream
是 Java 中用于从文件读取原始字节的类,继承自 InputStream
抽象类。
1. 核心特点
特性 | 说明 |
---|---|
继承关系 | InputStream → FileInputStream |
数据单位 | 字节(8bit) |
用途 | 读取二进制文件(如图片、音频、PDF等) |
是否缓冲 | 默认无缓冲(需配合 BufferedInputStream 使用) |
线程安全 | 否 |
2. 构造方法
java
// 1. 通过文件路径创建
FileInputStream fis = new FileInputStream("test.txt");// 2. 通过File对象创建
File file = new File("test.txt");
FileInputStream fis = new FileInputStream(file);// 3. 通过文件描述符创建(高级用法)
FileDescriptor fd = new FileDescriptor();
FileInputStream fis = new FileInputStream(fd);
3. 核心方法
方法 | 作用 |
---|---|
int read() | 读取单个字节(返回0-255,-1表示结束),调用一次read()方法则读取一个字节,返回读到的字节本身。(例如,信息为a,则返回一个97),如果读不到任何数据则返回-1 |
int read(byte[] b) | 读取字节到数组,返回实际读取的字节数(一次最多读取到b.length个字节) |
int read(byte[] b, int off, int len) | 从偏移量off开始读取len个字节到数组 |
long skip(long n) | 跳过n个字节 |
void close() | 关闭流 |
FileChannel getChannel() | 获取关联的FileChannel(NIO相关) |
int available() | 返回预估计流当中剩余的字节数量(意思就是:还剩下几个字节没有读取) |
二、使用示例
1. 基础读取文件
java
try (FileInputStream fis = new FileInputStream("data.bin")) {int data;while ((data = fis.read()) != -1) { // 每次读取1字节System.out.print((char) data); // 转为字符输出(仅适用于文本)}
} // try-with-resources自动关闭流
2. 高效读取(缓冲区)
java
try (FileInputStream fis = new FileInputStream("largefile.bin");BufferedInputStream bis = new BufferedInputStream(fis)) { // 添加缓冲byte[] buffer = new byte[1024];int bytesRead;while ((bytesRead = bis.read(buffer)) != -1) {// 处理buffer中的数据}
}
3. 读取到字节数组
java
File file = new File("data.bin");
byte[] fileData = new byte[(int) file.length()];
try (FileInputStream fis = new FileInputStream(file)) {fis.read(fileData); // 一次性读取全部内容
}
三、记忆技巧
1. 名称解析法
"File + Input + Stream"
File:操作文件
Input:输入(读取)
Stream:字节流
2. 对比记忆法
对比类 | 方向 | 数据单位 | 典型用途 |
---|---|---|---|
FileInputStream | 读取 | 字节 | 图片、压缩包等二进制文件 |
FileOutputStream | 写入 | 字节 | 文件下载、数据存储 |
FileReader | 读取 | 字符 | 文本文件(自动处理编码) |
3. 使用场景联想
-
图片处理:
FileInputStream
+ImageIO.read()
-
文件复制:
FileInputStream
+FileOutputStream
-
加密解密:读取原始字节后进行加密运算
4. 常见误区提醒
❌ 错误用法:直接读取文本文件(可能乱码)
✅ 正确做法:文本文件应使用 FileReader
或 InputStreamReader
四、面试高频问题
1. FileInputStream 和 BufferedInputStream 的区别?
-
FileInputStream:每次
read()
直接访问磁盘,性能低 -
BufferedInputStream:内置缓冲区(默认8KB),减少磁盘IO次数
2. 为什么读取文件要用 try-with-resources?
-
自动关闭资源:避免忘记调用
close()
导致文件句柄泄漏 -
代码简洁:不需要手动写
finally
块
3. 如何高效读取大文件?
java
// 方案1:使用缓冲流
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("large.bin"))) {byte[] buffer = new byte[8192]; // 8KB缓冲区while (bis.read(buffer) != -1) {// 处理数据}
}// 方案2:使用NIO的FileChannel(超大文件更高效)
4. read() 方法返回值的含义?
-
返回int:0-255表示字节值,-1表示文件结束
-
注意:必须用int接收,byte会无法区分-1和255
五、总结图示
mermaid
flowchart TDA[FileInputStream] --> B[读取二进制文件]A --> C[核心方法: read/skip/close]A --> D[需配合缓冲流提升性能]B --> E[图片/音频/PDF等]D --> F[BufferedInputStream]
一句话总结:
"FileInputStream读字节,无缓冲性能低,文本文件别用它,记得关闭保安全"