offset理解
好问题,offset 是字节流读写里最容易卡壳的地方。我用"一排格子"的比喻讲清这三个参数。
一句话先记住
Read(buffer, offset, count) 和 Write(buffer, offset, count) 的意思都是:
从数组的第
offset个格子开始,搬count个字节。
三个参数分别是什么
| 参数 | 类型 | 中文 | 作用 |
|---|---|---|---|
byte[] buffer |
字节数组 | 容器/水桶 | 读:用来"接"字节;写:从这里面"取"字节 |
offset |
int | 起点位置 | 从第几个格子开始(从 0 数) |
count |
int | 数量 | 这次最多搬多少个字节 |
1. byte[] buffer —— 装字节的容器
就是一个普通的字节数组,比如 byte[] buf = new byte[1024]; 表示一块能装 1024 个字节的"水桶"。
- 读:流把字节灌进这个数组。
- 写:从这个数组里把字节取出来灌进流。
2. offset —— 从哪个格子开始(你不懂的这个)
数组里的格子编号是 0, 1, 2, 3...。offset 就是"别从 0 开始,从第 offset 格开始"。
数组 buf(长度 8),格子编号:
┌───┬───┬───┬───┬───┬───┬───┬───┐
│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │
└───┴───┴───┴───┴───┴───┴───┴───┘
▲ ▲
offset=0 offset=4
(从头开始) (从第5格开始)
Read(buf, 0, 5)→ 从格子 0 开始,填 5 个字节(占 0~4)。Read(buf, 4, 3)→ 从格子 4 开始,填 3 个字节(占 4~6),前面的 0~3 不动。
什么时候会用到 offset ≠ 0? 比如你一个大数组里前半截已经放了东西,想从中间接着放:
byte[] buf = new byte[10];
// 假设 buf[0..3] 已经有人放了数据
// 现在从流里读 3 个字节,接着放在 buf[4] 开始的位置
int n = stream.Read(buf, 4, 3); // 从格子4开始放,最多放3个
3. count —— 这次搬多少
"最多"搬 count 个。注意是"最多",不是"一定":流里不够 count 个时,Read 只会返回实际读到的个数(可能比 count 小),到文件末尾会返回 0。
最关键的实战套路(读文件必背)
因为 Read 不一定一次读完,标准写法是用循环 + 看返回值:
byte[] buf = new byte[1024];
int n; // n = 这次实际读到的字节数
while ((n = stream.Read(buf, 0, buf.Length)) > 0) // 从0开始,最多读满1024
{
// 注意:真正有效的只有 buf[0 .. n-1],不是整个 buf
// 比如 n=300,说明只装了前300个格子
}
这里 offset 用 0(从开头放),count 用 buf.Length(最多塞满整桶)。每次循环 n 是实际装了多少——这就是 offset/count 配合返回值用的核心。
写的时候也一样
// 把 buf 里"从格子2开始"的 4 个字节写进流
stream.Write(buf, 2, 4);
意思是:不管 buf 多长,只取第 2~5 格(共 4 个)写进去。
一句话总结:
byte[]= 装字节的水桶offset= 从第几个格子开始(0 起算,平时大多写 0)count= 这次最多搬几个字节(实际可能更少,看Read的返回值)

浙公网安备 33010602011771号