InputStream是输入流最顶层的父类,在世纪操作过程成需要利用多态去实现这个类。
package io; import java.io.IOException; /** * @author LH * 仿写InputStream类 * 输入流最顶层的父类 * 注意!:所有的stream流操作都是阻塞操作!!!! */ public abstract class LHInputStream { /** * 最大的跳过buffer缓冲区大小 */ private static final int MAX_SKIP_BUFFER_SIZE = 2048; /** * 从缓冲区中读取下一个字节,字节的值从0-255 如果没有读到字节数就直接返回-1 * 注意:这个方法会一直阻塞知道数据可获取 * * @return * @throws IOException */ public abstract int read() throws IOException; /** * 从缓冲区读取多个字节,将多到的多个字节的数据存入到数组b中 * 此方法会阻塞操作,直到下一个字节可获取 * * @param b 要存入的数组 * @param off 偏移量 * @param len 长度 * @return 返回本次存入的字符数量 */ 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) { //此处是判断参数作用,判断偏移量和偏移尺寸是否是正数 // 再者要判断要存入的数组是否能存的了,不然就抛出数据越界异常 throw new IndexOutOfBoundsException(); } else if (len == 0) { //直接在前面判断 return 0; } //读取当前的偏移位置的value,如果已经读到了文件的末尾则直接返回-1 //不明白此处为什么要这么做? int c = read(); if (c == -1) { return -1; } int i = 1; try { // 遍历 for (; i < len; i++) { c = read(); //如果读到了 -1 则提前终止 if (c == -1) { break; } b[off + i] = (byte) c; } } catch (IOException e) { System.out.println("InputSteam read occur some error" + e); } return i; } /** * 此方法重载了上面的那个方法,直接用存储数组的长度 * * @param b 存取的数组 * @return * @throws IOException */ public int read(byte[] b) throws IOException { return read(b, 0, b.length); } /** * 从缓冲区中跳过和丢弃字节,如果为0则没跳过,如果为负数同样如此 * * @param n * @return * @throws IOException */ public long skip(long n) throws IOException { if (n <= 0) { return 0; } //余留个数 long remaining = n; //每次读取的个数 int nr = 0; //获取要存入数组的最大尺寸 int size = (int) Math.min(MAX_SKIP_BUFFER_SIZE, n); byte[] skipBuffer = new byte[size]; //循环余留个数,判断条件其大与0 //此处可能超过最大的跳过大小,所以用了循环 while (remaining > 0) { nr = read(skipBuffer, 0, (int) Math.min(size, remaining)); if (nr < 0) { break; } remaining -= nr; } return n - remaining; } /** * 返回描述刻度的byte数组大小 * * @return * @throws IOException */ public int available() throws IOException { return 0; } /** * 释放资源 * @throws IOException */ public void close() throws IOException { } /** * 标记当前位置,多线程并发问题? * @param readlimit */ public synchronized void mark(int readlimit){ } /** * 重置位置 * @throws IOException */ public synchronized void reset() throws IOException{ throw new IOException(); } /** * 当前类是否支持标记 * @return */ public boolean markSupported(){ return false; } }