package java.io;
/**
* 字节输入流
*/
public class ByteArrayInputStream extends InputStream {
//字节数组
protected byte buf[];
//起始位/当前读取位置
protected int pos;
//标记位
protected int mark = 0;
//数组长度
protected int count;
/**
* 构造方法 根据传入数组初始化属性信息
* @param buf
*/
public ByteArrayInputStream(byte buf[]) {
this.buf = buf; //字节数组为传入数组
this.pos = 0; //起始位为0
this.count = buf.length; //长度为数组长度
}
/**
* 构造方法
* @param buf
* @param offset 起始位偏移量
* @param length 长度
*/
public ByteArrayInputStream(byte buf[], int offset, int length) {
this.buf = buf; //字节数组为传入数组
this.pos = offset; //起始位为传入偏移量位置
this.count = Math.min(offset + length, buf.length); //长度取(起始位+传入长度与数组长度)中较小的值
this.mark = offset; //标记位为偏移量位置
}
/**
* 读取一个字节
* 为什么需要 buf[pos++] & 0xff?
* buf[pos++] & 0xff 将pos位置的字节取出 按位与 0xff 将字节转为int类型
* 原因是byte表示范围为-128 ~ 127
* 而方法定义中 -1 是流读取结束的标志,此时 结束标志-1与实际读取到的字节位-1有冲突
* 所以将byte转为int 此时byte的-1被转为int的255 从而保证整个数据的读取完整性
*/
public synchronized int read() {
/**
* pos < count 当前位 小于 数组长度
* 是:
* buf[pos++] 获取pos位置的字节 并将pos值加1
* buf[pos++] & 0xff 将pos位置的字节转为int类型返回
* 否:
* 返回 -1
*
*/
return (pos < count) ? (buf[pos++] & 0xff) : -1;
}
/**
* 按长度读取
* @param b 待读取数组
* @param off 读取偏移量
* @param len 读取长度
*/
public synchronized int read(byte b[], int off, int len) {
if (b == null) { //待读取字节数组为空
throw new NullPointerException(); //报错 空指针
} else if (off < 0 || len < 0 || len > b.length - off) { //起始位偏移量小于0 或读取长度小于0 或读取长度大于待读取数组长度减偏移量
throw new IndexOutOfBoundsException(); //报错 索引越界
}
if (pos >= count) { //当前值大于等于数组长度时 表示已读取到结束位
return -1; //直接返回
}
int avail = count - pos; //定义剩余可读取长度量 为数组长度减去起始位
if (len > avail) { //如果读取长度大于剩余可读取长度
len = avail; //将读取长度重置为剩余可读取长度
}
if (len <= 0) { //如果读取长度小于等于0 表示不读取数据
return 0; //直接返回
}
/**
* 数组拷贝
* buf 原数组
* pos 原数组起始位
* b 目标数组
* off 目标数组起始位
* len 拷贝长度
*/
System.arraycopy(buf, pos, b, off, len);
pos += len; //起始位 = 原起始位 + 本次读取长度
return len; //返回读取长度
}
/**
* 跳过指定长度不读取
* @param n 需要跳过的长度
*/
public synchronized long skip(long n) {
long k = count - pos; //定义中间量 值为数组长度减去起始位长度 即剩余可读取长度
if (n < k) { //若需要跳过的长度小于剩余可读取长度时
k = n < 0 ? 0 : n; //中间量重新赋值 当需要跳过的长度小于0时 中间量为0 否则为需要跳过的长度
}
pos += k; //将起始位变更为 原起始位 + 需要跳过的长度
return k; //返回需要跳过的长度值
}
/**
* 返回剩余可读的字节数量
*/
public synchronized int available() {
return count - pos; //数组总长度 减去 当前位置
}
/**
* 判断当前流是否支持标记流
*/
public boolean markSupported() {
return true;
}
/**
* 标记读取位置,下次还可以从这里开始读取,使用前要看当前流是否支持,可以使用 markSupport() 方法判断
*/
public void mark(int readAheadLimit) {
mark = pos;
}
/**
* 重置读取位置为上次 mark 标记的位置
*/
public synchronized void reset() {
pos = mark;
}
/**
* 读取完,关闭流,释放资源
*/
public void close() throws IOException {
}
}
JDK1.8-ByteArrayInputStream类原码及分析
最新推荐文章于 2025-11-27 10:55:11 发布
463

被折叠的 条评论
为什么被折叠?



