文章目录
- 背景
- 示例
- 前置条件
- 使用 FileInputStream 流读取内容
- 参数详解
- 网上的错误解释
- 正确的解释
- 总结
背景
在使用Java的 IO过程中,肯定遇到过偏移量这个概念。网上也有很多人都解释过,但是有很多的人都被误导理解错了,也包括我。偏移量确实很容易理解错,刚开始我也理解错了。直到后来看BufferedOutputStream 源码的时候就越发感觉不对劲。
下面就详细解释一下偏移量到底什么意思。
在 FileInputStream 中的public int read(byte b[], int off, int len)方法中第二个参数,int off 就是偏移量的意思。
示例
前置条件
先在 F:\FilesExample\A.txt 文件中加入待读取的内容
ABCDEFG
使用 FileInputStream 流读取内容
public static void main(String[] args) {
String filePath = "F:\\FilesExample\\A.txt";
// 创建字节输入流
try ( FileInputStream fis = new FileInputStream(filePath)){
// 创建装数据的数组
byte[] bytes = new byte[10];
// 调用read方法读取数据
fis.read(bytes, 2, 3);
// 打印读出来的数据
for (int i = 0; i < bytes.length; i++) {
System.out.println(bytes[i]);
}
} catch (IOException e) {
e.printStackTrace();
}
}
注意这句代码
fis.read(bytes, 2, 3);
注意这里的参数
- 第一个参数是存放即将读出来的数据的字节数组。
- 第二个参数是偏移量,这里先传个2。
- 第三个参数是要读取的长度。
参数详解
第一个参数不用过多解释,就是存放数据的数组。
第二个参数代表偏移量,就是有歧义的地方。
网上的错误解释
偏移量的意思就是,读数据的时候从上一次读的最后位置接着往下读,比如第一次读了1024个字节,那么下一次就从1025开始读
这句话哪里错了?
这句话的意思是说,偏移量是数据流的偏移量。在上一次读到某个位置后,偏移量就记录下那个位置的坐标,下一次读取的时候,接着往后读。
如果按照这个意思来读取的话,我们传入的参数是2,也就是数据流的偏移量是2,那就该从下表为2的地方开始读,那应该跳过“A”,“B”两个字节,读取结果应该是”C“,”D“,”E“三个数据。
我们来运行一下,结果显示:
0
0
65
66
67
0
0
0
0
0
这里有两个地方需要注意一下
- 读取的字节都是ASCII码。 65代表大写字母”A“ ,66代表大写字母”B“,67代表大写字母”C“
- 字节数组空的位置会初始化成0。
结果和预想的完全不一样。(居然无论如何都是从数据流的最开始0下标开始读取,只不过存放在传入的数组位置变了)
正确的解释
其实偏移量 真正指的是这个存放数据的数组的偏移量(第一个参数)。
使用这个解释去理解一下这个示例。
读取3个字节(第三个参数)的数据,存放在bytes数组中(第一个参数),存放在数组中的什么位置呢?那就得看偏移量了,这里偏移量是2(第二个参数),就表示存放在数组中下标为2的位置开始,数据依次往后展开。也就是说,假设读取了两个字节的数据,就放在数组的3、4号坑(数组是从0开始的),假设读取了3个字节的数据,就放在数组的3、4、5号坑…
总结
Java IO流中的偏移量是指接收数据的数组(或叫缓冲区)的偏移量,并不是数据流的偏移量。