JAVA-IO-InputStream解析

Java.io.InputStream类声明了三个基本方法用来把byte数据写入到流中。当然也有用于关闭和刷新的流,查看还有多少数据可以读,略过一些输入,在流中标记一个位置然后重置到那个位置,还有决定标记和重设是否是支持的。

  public abstract int read() throws IOException
  public int read(byte[] data) throws IOException
  public int read(byte[] data, int offset, int length) throws IOException
  public long skip(long n) throws IOException
  public int available() throws IOException
  public void close() throws IOException
  public synchronized void mark(int readLimit)
  public synchronized void reset() throws IOException
  public boolean markSupported()

InputStream中最基本的方法是read,这个方法读入一个无符号的byte类型,然后返回它的整型值。就像大多数的IO方法一样,read方法也会有异常抛出,如果read中无数据可读,你不会受到异常,而是返回-1。用这个作为流结尾的标志。如下的代码展示了如何catch IOException和查看是否为结尾。

    try{
        int[] data = new int[10];
        for(int i=0;i<data.length;i++) {
            int datum = System.in.read();
            if (datum == -1) break;
            data[i] = datum;
        }
    } catch (IOException e ) {
        System.err.println("Couldn't read from System.in!");
    }

read方法等待或者阻塞直到byte数据可用而且准备就绪。Input和Output可能会很慢,所以如果你的程序在执行其他重要的事情。你应该把IO操作放在它们自己的线程当中。下面这个类

public class StreamPrinter {
  InputStream theInput;
  
  public static void main(String[] args) {
    StreamPrinter sr = new StreamPrinter(System.in);
    sr.print();
  }

  public StreamPrinter(InputStream in) {
    theInput = in;
  }
  
  public void print() {
    try{
      while(true) {
        int datum = theInput.read();
        if (datum == -1) break;
        System.out.println(datum);
      }
    } catch (IOException e) {
      System.err.println("couldn't read from system in")
   }
  }
}

第一个read方法读入一批连续数据到byte数组中,第二个尝试读入一定长度的data从offset开始到byte数组。它们两个都不保证读入任意数量的byte。
如果你打算从System.in读入10byte的数据,如下的代码可以完成操作:

  byte[] b = new byte[10];
  System.in.read(b);

但是,并不是每次read都可以拿到你想要的那么多数据。但是这行代码也不能阻止你试图往read中写入超过容量的数据,如果你这么做了,就会导致ArrayIndexOutOfBoundsException.
如下的代码利用循环,确保尽可能多得获得数据:

  byte[] b = new byte[100];
  int offset = 0;
  while(offset <b.length) {
    int bytesRead = System.in.read(b, offset,b.length-offset);
    if(bytesRead==-1) break;
    offset+=bytesRead;
  }

尽管上述的代码可以尽可能多得获取数据,但是并不能规避异常的发生。所以,如果在你尝试读它们之前,你可以知道有多少数据将要被读,这将会非常方便。InputStream中的available方法可以告诉你答案
你可以手动操作代码来忽略掉一部分的数据,但JAVA还是提供了skip方法用来跳过给定byte数的方法

  public long skip(long bytesToSkip) throws IOException

返回值是实际略去的byte数。如果返回-1,则证明剩下的部分都被忽略了。通常来说skip方法比自己手动忽略要快。
并不是所有的流都需要被关闭,比如System.in。但是跟文件或者网络相关的连接还是需要被关闭的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1 IONo18 1.1IO框架 【 IO:Input Output 在程序运行的过程中,可能需要对一些设备进...
    征程_Journey阅读 4,551评论 0 1
  • 在经过一次没有准备的面试后,发现自己虽然写了两年的android代码,基础知识却忘的差不多了。这是程序员的大忌,没...
    猿来如痴阅读 8,131评论 3 10
  • 一、流的概念和作用。 流是一种有顺序的,有起点和终点的字节集合,是对数据传输的总成或抽象。即数据在两设备之间的传输...
    布鲁斯不吐丝阅读 13,444评论 2 95
  • 入夏了,夜里很适合来回走走。喜欢这个季节这个时候的温度。 村里头的路灯开到凌晨一点多,不下雨的天气天上就会冒出很多...
    9f867c0ed88a阅读 1,364评论 0 0
  • 春兰秋菊各一枝, 常见月季占四时。 更喜天天胜春花, 何忧年年无乐事? 注:后两句化用了【宋】周必大的“莫思乐事年...
    梅心梅飞阅读 3,493评论 10 14

友情链接更多精彩内容