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。但是跟文件或者网络相关的连接还是需要被关闭的。