InputStream类

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;
    }

}

  

猜你喜欢

转载自www.cnblogs.com/KanHin/p/10063657.html