zoukankan      html  css  js  c++  java
  • 输入流之顶层抽象InputStream

    该类是所有二进制输入流的的抽象父类

    类中主要方法解释说明如下

    (1)public abstract int read() throws IOException;

      该方法是从输入流中读取下一个字节,返回的值字节是一个范围从0到255之间的int数。如果读到输入流的未尾,则返回-1。 同时该方法会一直阻塞直到输入流中数据可用,或者流读完毕或者抛出异常。

    下面以FileInputStream来举个示例。

    读取一个文件test.txt. 该文件内容“abcdefghijklmn”

      @Test
        public void testRead() throws IOException {
            FileInputStream inputStream = new FileInputStream("E:\360downloads\wpcache\srvsetwp\test.txt");
            while (true) {
                int read = inputStream.read();
                if (read == -1) {
                    break;
                }
                System.out.println(read + "," + (char) read);
            }
        }

    打印结果如下: 

    97,a
    98,b
    99,c
    100,d
    101,e
    102,f
    103,g
    104,h
    105,i
    106,j
    107,k
    108,l
    109,m
    110,n

    (2)public int read(byte b[]) throws IOException;

      从输入流中读取一些字节存储到b数组中,返回实际读取的长度。如果b的大小为0,则不会从输入流中读取字节,否现读取的第一个字节放入b[0],第二个字节放b[1] ,依次类推,该方法也是阻塞的,直到流读可用,或者读完,或者抛异常。

    示例1:  

       @Test
        public void testReadBytes() throws IOException {
            FileInputStream inputStream = new FileInputStream("E:\360downloads\wpcache\srvsetwp\test.txt");
            byte[] buf = new byte[100];
            int read = inputStream.read(buf);
            System.out.println(read);  //14
            String readContent = new String(buf, 0, read);
            System.out.println(readContent); //abcdefghijklmn
        }

    示例2:

     @Test
        public void testReadBytes() throws IOException {
            FileInputStream inputStream = new FileInputStream("E:\360downloads\wpcache\srvsetwp\test.txt");
            byte[] buf = new byte[5];
            int read = inputStream.read(buf);
            System.out.println(read);  //5
            String readContent = new String(buf, 0, read);
            System.out.println(readContent); //abcde
        }

    示例3:

     @Test
        public void testReadBytes() throws IOException {
            FileInputStream inputStream = new FileInputStream("E:\360downloads\wpcache\srvsetwp\test.txt");
            byte[] buf = new byte[5];
            int len = 0;
            while ((len = inputStream.read(buf)) != -1) {
                String readContent = new String(buf, 0, len);
                System.out.println(readContent);
            }
    
        }

    示例3打印结果:

    abcde
    fghij
    klmn

    由示例3可知,read(byte b[])方法,每次都会从输入流中读取b.length个字节,下次读流时,接着上一次的未尾开始。

    (3)public long skip(long n) throws IOException;

       从输入流中跳过n个字节或者说是丢弃掉n个字节

      @Test
        public void testSkip() throws IOException {
            FileInputStream inputStream = new FileInputStream("E:\360downloads\wpcache\srvsetwp\test.txt");
            byte[] buf = new byte[14];
            long skip = inputStream.skip(4); 
            System.out.println("skip:"+ skip); // skip:4
    
            int read = inputStream.read(buf);
            System.out.println("read:"+read); //read:10
    
            String readContent = new String(buf, 0, read);
            System.out.println(readContent); //efghijklmn
        }

    从上面的打印结果可知,skip确实丢弃掉了4个字节(abcd), 后面read时直接从输入流中的第5个字节开始读取,所以最终打印是“efghijklmn”

    (4)public int available() throws IOException ;

        检测输入流中还可以read读取的字节个数

     @Test
        public void testAvailable() throws IOException {
            FileInputStream inputStream = new FileInputStream("E:\360downloads\wpcache\srvsetwp\test.txt");
    
            int available = inputStream.available();
            System.out.println("第一次测试available:"+available);  //第一次测试available:14
    
            long skip = inputStream.skip(4);
            System.out.println("skip:" + skip); // skip:4
    
            available = inputStream.available();
            System.out.println("第二次测试available:"+available); // 第二次测试available:10
    
            byte[] buf = new byte[5];
            int read = inputStream.read(buf);
            System.out.println("read:" + read); //read:10
    
            available = inputStream.available();
            System.out.println("第三次测试available:"+available);  //第三次测试available:5
    
            String readContent = new String(buf, 0, read);
            System.out.println(readContent); //efghijklmn
        }

    由打印结果,可以很容易的理解available()方法的含义。

    第1次 inputStream中可读字节14;skip丢弃掉4个字节后,第2次 检测 inputStream中可读字节等于 14 - 4 = 10 个; 然后从inputStream中read读取5个字节后,第3次打印 只剩5个可用字节了。

    (5)public synchronized void mark(int readlimit) ;

      

    先来做一个测试:

     @Test
        public void testMarks() throws IOException {
            FileInputStream inputStream = new FileInputStream("E:\360downloads\wpcache\srvsetwp\test.txt");
    
            byte[] buf = new byte[5];
            int read = inputStream.read(buf);
            // 第1次从inputStream流中读5个字节
            System.out.println(new String(buf,0,read));
            // 打个标识
            inputStream.mark(5);
            // 第2次从inputStream流中读取5个字节
            int secondRead = inputStream.read(buf);
            System.out.println(new String(buf,0,secondRead));
    
            // 第3次从inputStream流中读取4个字节(只剩下4个字节了)
            int thirdRead = inputStream.read(buf);
            //注意:这里不要用buf.length, 因为本次没有5个字节,不能将第2次读取到buf数组中的值全部覆盖
            System.out.println(new String(buf,0,thirdRead));
        }

    本次实验,第1次读取inputStream中的前5个字节 , 第2次读取inputStream中的6到10个字节, 第3次读取inputStream中未尾4个字节 , remark()方法好像没有啥用吧。好像还真的是,不过请先看看markSupported()方法

    请看下面测试:

     @Test
        public void testMarkSupport() throws IOException {
            FileInputStream inputStream = new FileInputStream("E:\360downloads\wpcache\srvsetwp\test.txt");
            boolean b = inputStream.markSupported();
            System.out.println(b); //false
        }

    上次测试打印false ,  表示FileInputStream这种类型的流,根本就不支持mark()或者reset()方法。所以,尴尬。。。

    下面找一个支持mark(),reset()的输入流是测试一把

     @Test
        public void testMarkAndReSet() throws Exception{
            String content = "abcdefghijklmn";
            InputStream inputStream = new ByteArrayInputStream(content.getBytes());
    
            System.out.println("是否支持mark:"+ inputStream.markSupported()); //是否支持mark:true
            byte[] buf = new byte[5];
            int read = inputStream.read(buf);
            // 第1次从inputStream流中读5个字节
            System.out.println(new String(buf,0,read));  //abcde
            // 打个标识
            inputStream.mark(5);
            // 第2次从inputStream流中读取5个字节
            int secondRead = inputStream.read(buf);
            System.out.println(new String(buf,0,secondRead)); // fghij
    
            // 重置
            inputStream.reset();
    
            // 第3次从inputStream流中读取5个字节
            int thirdRead = inputStream.read(buf);
            System.out.println(new String(buf,0,thirdRead));  // fghij
    
            // 第4次从inputStream流中读取5个字节
            int forthRead = inputStream.read(buf);
            System.out.println(new String(buf,0,forthRead)); //klmn
    
    
        }

    哈,仔细观察打印结果,发现mark+reset后, 可以重复读取流中数据 。 其实,mark+reset就是这么点功能。

    好了,InputStream这个输入流的顶层抽象类就写完了,主要也就这么几个方法!

  • 相关阅读:
    < java.util >-- Set接口
    Codeforces 627 A. XOR Equation (数学)
    Codeforces 161 B. Discounts (贪心)
    Codeforces 161 D. Distance in Tree (树dp)
    HDU 5534 Partial Tree (完全背包变形)
    HDU 5927 Auxiliary Set (dfs)
    Codeforces 27E. Number With The Given Amount Of Divisors (暴力)
    lght oj 1257
    Codeforces 219D. Choosing Capital for Treeland (树dp)
    Codeforces 479E. Riding in a Lift (dp + 前缀和优化)
  • 原文地址:https://www.cnblogs.com/z-qinfeng/p/11787136.html
Copyright © 2011-2022 走看看