美文网首页java语言基础程序员
【Java IO】 二、从InputStream源码说起

【Java IO】 二、从InputStream源码说起

作者: 6d898101c4c9 | 来源:发表于2018-11-16 03:39 被阅读58次

    此类是一个抽象类,只是对其余继承它的类的一个规范(如 FileInputStream等),并没有具体实现。

    来看看它的定义及方法吧

    这是该类的定义,其实现了closeable这个接口,简单来说就是定义的这个数据流对象要有一个close方法,来释放该流对象所占用的资源。

    public abstract class InputStream implements Closeable
    
    public interface Closeable extends AutoCloseable {
        public void close() throws IOException;
    }
    

    下面是其中重要的抽象方法,子类必须实现

    JDK中的注释如下:
    从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞。
    子类必须提供此方法的一个实现。

    public abstract int read() throws IOException;
    

    简单来说,下面的方法就是将调用read()得到的int 值,放入byte数组中
    off是从哪开始放,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) {
                throw new IndexOutOfBoundsException();
            } else if (len == 0) {
                return 0;
            }
    //得到下一个字节,如果为-1则表示数据读取完毕返回
            int c = read();
            if (c == -1) {
                return -1;
            }
       
            b[off] = (byte)c;
    
            int i = 1;
            try {
                for (; i < len ; i++) {
                    c = read();
                    if (c == -1) {
                        break;
                    }
    //只要int 值不等于-1且byte数组还有空间,就将值放入。
                    b[off + i] = (byte)c;
                }
            } catch (IOException ee) {
            }
            return i;
        }
    

    还有一个方法,就是将数据放满这个byte数组。

      public int read(byte b[]) throws IOException {
            return read(b, 0, b.length);
        }
    

    下面的方法是用来跳过指定的n个字节数,其实就是调用read()方法,读取n个byte,也就相当于是跳过了。

        public long skip(long n) throws IOException {
            //剩余需要跳过的字节数
            long remaining = n;
            int nr;
        
            if (n <= 0) {
                return 0;
            }
            //可跳过的最大值,如n小于这个值,可一次跳过,如大于n,则分多次跳过
            int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);
            byte[] skipBuffer = new byte[size];
            //只要还有需要跳过的字节且流中还有数据
            while (remaining > 0) {
                
                nr = read(skipBuffer, 0, (int)Math.min(size, remaining));
                //如果流中已没有数据,返回。
                if (nr < 0) {
                    break;
                }
                //计算还需跳的字节数
                remaining -= nr;
            }
    
            //返回实际跳过的字节数
            return n - remaining;
        }
    

    代码小练习:

    因为inputStream是抽象类,没办法new (因为方法根本就没实现),所以只能选一个继承了inputStream的子类,就FileInputStream吧。

    一。首先新建txt文本:为简单起见,只输入五个字符abcde


    }LSOYRKJC3FD2EP66Z6X{UW.png

    二。代码如下

     public static void main(String[] args) throws Exception {
    
            File file = new File("G:\\file\\1.txt");
    
            InputStream fileInputStream = new FileInputStream(file);
            int i = 0;
            //跳过windows系统自动在txt文件首添加的三个byte
            fileInputStream.skip(3);
    
            while (true) {
                i = fileInputStream.read();
                if (i == -1) {
                    break;
                }
                //输出的是 txt文件的ASCII码,和其对应的字符
                System.out.print(i + ":" + (char) i + " ");
            }
        }
    

    输出为:


    1.png

    相关文章

      网友评论

        本文标题:【Java IO】 二、从InputStream源码说起

        本文链接:https://www.haomeiwen.com/subject/frhpfqtx.html