数据与流
byte[] b = new byte[1024];、in.read(b)和数组转换问题
byte[] b = new byte[1024];:创建一个长度为1024的字节数组b,一次最多可以存放从流中获取的1024个字节
in.read(b) :从输入流 in 中,读取最多b.length个字节数据,存放到字节数组 b 中(从索引0开始);返回实际读取的字节数,当读取到输入流的末尾时返回 -1
直观理解: 想象你有1024个连续的小盒子排成一排:
┌───┬───┬───┬───┬───┬───┬──────┬────┬────┐
│ │ │ │ │ │ │ ... │ │ │ ← 1024个小盒子
│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ │1022│1023│
└───┴───┴───┴───┴───┴───┴──────┴────┴────┘
数组索引 ... 数组索引
每个小盒子可以存放一个字节(byte)
完整读取过程图解
场景:读取一个2000字节的文件
byte[] b = new byte[1024]; // 创建1024个空盒子
// 第一次读取:从读取1024字节
int bytesRead1 = in.read(b); // bytesRead1 = 1024
第一次读取后,数组状态:
┌─────────────────────────────────────────────────┐
│ H e l l o W o r l d ! (1024个实际数据) │ ← 前1024个字节是文件内容
└─────────────────────────────────────────────────┘
// 第二次读取:再读取976字节(2000-1024=976)
int bytesRead2 = in.read(b); // bytesRead2 = 976
第二次读取后,数组状态:
┌─────────────────────────────────────────────────┐
│ 新内容(976字节) │ 旧数据(48字节) │
└─────────────────────────────────────────────────┘
↑ ↑
新的内容 第一次读取的最后48字节没被覆盖
(976字节)
因为第二次只读取了976字节,只覆盖了数组的前976个位置,后面48个位置还保留着第一次读取的数据。
这就带来一个问题:字符串转换可能包含垃圾数据
// 问题代码
byte[] b = new byte[1024];
while(in.read(b)!=-1) {
System.out.println(new String(b)); // ❌ 整个数组都被转换
// 假设文件内容只有10字节,但数组是1024字节
// 前10字节是文件内容,后1014字节是上次读取的残留数据!
}
// 正确做法:只转换实际读取的部分
byte[] b = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(b)) != -1) {
System.out.println(new String(b, 0, bytesRead)); // ✅ 只转换实际读取的部分
}
记住:流读取时,要求总是只处理实际读取的部分,而不是整个数组!
String((byteArray, startIndex, length)方法
参数结构:
new String(byteArray, startIndex, length)
| 参数 | 类型 | 含义 | 说明 |
|---|---|---|---|
| 第一个参数 | byte[] | 字节数组 | 包含原始字节数据的数组 |
| 第二个参数 | int | 起始索引 | 从数组的哪个位置开始转换(0表示从第一个字节开始) |
| 第三个参数 | int | 转换长度 | 要转换多少个字节 |
如何确定类路径下的资源文件路径
1. 理解项目结构(以Maven项目为例)
my-project/
├── src/
│ ├── main/
│ │ ├── java/ ← 源代码目录
│ │ │ └── com/example/MyApp.java
│ │ └── resources/ ← 类路径资源目录(核心!)
│ │ ├── config.properties
│ │ ├── images/
│ │ │ └── logo.png
│ │ └── templates/
│ │ └── index.html
│ └── test/
│ └── resources/ ← 测试资源目录
└── target/
└── classes/ ← 编译后的类路径(真正运行时)
2. 确定类路径下的资源文件路径的方法
规则:src/main/resources/ 下的目录结构就是类路径的目录结构
| 文件在项目中的位置 | 类路径下的资源文件路径 |
|---|---|
src/main/resources/config.properties | "config.properties" |
src/main/resources/images/logo.png | "images/logo.png" |
src/main/resources/templates/index.html | "templates/index.html" |