package java.io;
public abstract class InputStream implements Closeable {
// 当使用skip方法时,最大的buffer size大小
private static final int MAX_SKIP_BUFFER_SIZE = 2048;
/** 抽象方法 子类实现 读取数据*/
public abstract int read() throws IOException;
/**
* 传入字节数组 返回数组长度
* 实际调用 根据数组、起始位置、待读取长度参数返回数组长度 起始位为0 长度为数组长度
* 将读取到的数据放在 byte 数组中,该方法实际上调用read(byte b[], int off, int len)方法
*/
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
/**
* 从第 off 位置读取<b>最多(实际可能小于)</b> len 长度字节的数据放到 byte 数组中,流是以 -1 来判断是否读取结束的;
* 此方法会一直阻塞,直到输入数据可用、检测到stream结尾或引发异常为止。
* @param b 待读取数组
* @param off 起始读取位置
* @param len 待读取长度
*/
public int read(byte b[], int off, int len) throws IOException {
if (b == null) { //数组为空时报错 空指针
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {//起始位小于0 或待读取长度小于0 或待读取长度大于数组长度-起始位 报错 索引越界
throw new IndexOutOfBoundsException();
} else if (len == 0) {//待读取长度为0 直接返回
return 0;
}
int c = read();//读取当前位字节 读取成功将当前位+1 读取不到返回-1
if (c == -1) {//当前位读取结果为-1 则直接返回
return -1;
}
b[off] = (byte)c;//将当前位字节放入数组
int i = 1;
try {
for (; i < len ; i++) {//根据待读取长度遍历
c = read();//读取当前位字节 读取成功将当前位+1 读取不到返回-1
if (c == -1) {//当前位读取结果为-1 推出循环
break;
}
b[off + i] = (byte)c;//将读取的字节存入数组中
}
} catch (IOException ee) {
}
return i;//返回读取的字节长度
}
/**
* 跳过指定个数的字节不读取
*/
public long skip(long n) throws IOException {
long remaining = n;//将传入长度另存为待读取长度
int nr;//创建暂存值
if (n <= 0) {//如果传入长度小于或等于0 则直接返回
return 0;
}
int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);//将待读取长度与最大流长度作比较 取小的作为待创建数组长度
byte[] skipBuffer = new byte[size];//创建空数组 长度为待读取长度或最大skip长度
while (remaining > 0) {//当待读取长度大于 则执行操作
nr = read(skipBuffer, 0, (int)Math.min(size, remaining));//从0位置开始 每次读取size或待读取的长度(当待读取长度过长时,取skip最大可读取长度,分多次读取,直到待读取长度小于skip最大可读长度;当待读取长度小于skip最大可读长度时,直接取待读取长度,一次读完)
if (nr < 0) {//如果读取后的结果小于0 说明该次未读取到 即已经完全读取了指定的长度
break;//退出读取
}
remaining -= nr;//若读取后结果大于等于0 则将读取的长度从剩余待读取长度中去除 进行下一次读取
}
return n - remaining;//返回传入长度减去待读取长度 此时待读取长度应该为0 即返回的是传入长度 该长度内的信息已存入skipBuffer数组中
}
/**
* 返回可读的字节数量
*/
public int available() throws IOException {
return 0;
}
/**
* 读取完,关闭流,释放资源
*/
public void close() throws IOException {}
/**
* 标记读取位置,下次还可以从这里开始读取,使用前要看当前流是否支持,可以使用 markSupport() 方法判断
*/
public synchronized void mark(int readlimit) {}
/**
* 重置读取位置为上次 mark 标记的位置
*/
public synchronized void reset() throws IOException {
throw new IOException("mark/reset not supported");
}
/**
* 判断当前流是否支持标记流,和上面两个方法配套使用。默认是false,由子类方法重写
*/
public boolean markSupported() {
return false;
}
}
JDK1.8 InputStream类原码及分析
于 2024-12-03 15:10:27 首次发布
1276

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



