美文网首页
13. Java IO: InputStream

13. Java IO: InputStream

作者: kopshome | 来源:发表于2017-11-21 15:49 被阅读0次

    想要查看此教程的目录请点击:Java IO教程目录贴地址


    InputStream是Java IO中所有输入流的基类。它的子类包括FileInputStream,BufferedInputStream和PushbackInputStream等。想要查看所有详细的列表,请看“Java IO Overview”章节。

    InputStreams and Sources

    InputStream经常被用来连接一些数据源,例如文件,网络连接,管道等等。查看更详细的信息参考“Java IO Overview”章节

    InputStream例子

    它用来读取字节数据,每次读取一个字节。下面是一个相关例子:

    nputStream inputstream = new FileInputStream("c:\\data\\input-text.txt");
    
    int data = inputstream.read();
    while(data != -1) {
      //do something with data...
      doSomethingWithData(data);
    
      data = inputstream.read();
    }
    inputstream.close();
    

    这个例子中创建了一个FileInputStream实例。FileInputStream是InputStream的子类所以它可以InputStream类型的变量。
    注意:为了代码清晰,这里并没有考虑处理异常的情况。想学习更多可以看“Java IO Exception Handling”

    Java7开始,你可以用try-with-resources去确保InputStream在使用后可以关闭。具体的用法可以参考上面Java异常处理的文章,但是这里有一个例子:

    try( InputStream inputstream = new FileInputStream("file.txt") ) {
    
        int data = inputstream.read();
        while(data != -1){
            System.out.print((char) data);
            data = inputstream.read();
        }
    }
    

    只要线程已经执行出try代码块,inputstream就会被关闭。

    read()

    InputStream的read()方法返回一个int类型的值,这个值是每次读取的字节的值。下面是一个相关的例子:

    int data = inputstream.read();
    

    你也可以把int值强转成为一个char类型的:

    char aChar = (char) data;
    

    InputStream的子类有可能扩展了read()方法。例如,DataInputStream允许读取java基本类型,像int、long、float、double、boolean等等。当然这些有相应的方法,readBoolean(),readDouble()等等。

    Stream的结束

    如果read()方法返回 -1,就说明流到已经全部读取完毕。这里的 -1 是int类型的,不是byte或short。这里是有些不同的!
    当流去读完毕的时候,你可以关闭它了

    read(byte[])

    InputStream有两个read()方法,参数是一个字节数组。这些方法是:

    • int read(byte[])
    • int read(byte[], int offset, int length)

    每次读取一个字节数组显然要比每次读取一个字节要快的多,所以只要有可能,你可以使用这类的方法来替代read()方法。

    read(byte[])方法会读取所有数据到数组中。它会返回一个int值,来告诉实际读取的字节数。万一实际读取的字节数要比提供的字节少,那么字节数组的其余部分将包含与读取开始之前所做的相同的数据。要记住去检查返回的int值,看实际取得的字节数有多少。
    read(byte[], int offset, int length)方法也是读数组到数组中,但是可以根据参数来规定开始的偏移量和一共读取多少长度。返回值和read(byte[])方法的含义相同。

    两个方法相同的地方都是如果返回值是 -1 ,代表读取结束。

    下面的例子为如何使用InputStream的read(byte[])方法:

    InputStream inputstream = new FileInputStream("c:\\data\\input-text.txt");
    
    byte[] data      = new byte[1024];
    int    bytesRead = inputstream.read(data);
    
    while(bytesRead != -1) {
      doSomethingWithData(data, bytesRead);
    
      bytesRead = inputstream.read(data);
    }
    inputstream.close();
    

    首先,上面代码创建了一个字节数组。然后创建了一个叫bytesRead的int类型变量,去接受每次调用read(byte[])方法的返回值。
    在循环里,doSomethingWithData()方法被循环调用,传递进去读了多少字节和字节数组。在循环的最后把数据重新读到数组一遍。

    不用花太多精力放在研究怎么样使用read(byte[], int offset, int length)方法来替换read(byte[])。你完全可以在任何时候用read(byte[], int offset, int length)替换掉read(byte[])方法。

    mark()和reset()

    InputStream类中有两个方法mark()和reset(),但是它的子类不一定有支持(或者说子类有没有重写此方法)。

    如果一个InputStream的子类支持这两个方法,子类会重写markSupported()方法并返回 true。相反的,如果返回false,则子类不支持这两个方法。

    mark()方法在InputStream设置一个内部的标记,标记在流中哪个数据到目前为止已经被读取。使用InputStream的代码,可以根据这个标记位来继续读取数据。

    在读取流的过程汇总,如果想退回到标记的那点上,可以调用reset()方法。然后InputStream退回到标记位上,开始从这个位置开始返回数据。这当然会导致多次返回一些数据

    当实现一个解析器时,会经常用到这两个方法。解析器读取一个InputStream时会提前读,如果解析器没有找到它想要的,他可能需要回退并且将已读数据和其他的数据进行匹配。

    相关文章

      网友评论

          本文标题:13. Java IO: InputStream

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