输入流(InputStream)
输入流的概念:读取外部的信息,并读入到程序的通信通道。
InputStream不是一个接口,而是一个抽象类,其中最重要的方法是int read();
方法:
这个方法会读取输入流的下一个字节,并返回字节表示的int值。若返回-1,则表示读到末尾。
FileInputStream是InputStream的一个子类,其实现了readFile()方法。
在操作InputStream和OutputStream的过程中,需要及时释放不需要的资源,调用Close方法。
在读取过程中如果出现错误,会导致无法运行close方法,因此,在做IO操作时,要使用try…finally,保证无论是否发生异常都能正确关闭IO。
java7的新特性,由编译器帮助我们释放资源,需要用到try(resource):
public void readFile() throws IOException {
try (InputStream input = new FileInputStream("src/readme.txt")) {
int n;
while ((n = input.read()) != -1) {
System.out.println(n);
}
} // 编译器在此自动为我们写入finally并调用close()
}
缓冲
在读取流时,一次读取一个字节不是高效的方法,InputStream提供了两个重载方法来支持读取多个字节:
- int read(byte[] b):读取若干字节并填充到byte[]数组,返回读取的字节数
- int read(byte[] b, int off, int len):指定byte[]数组的偏移量和最大填充数
在上述方法中,byte[]数组作为缓冲区,将读取到的字节放入缓冲区中,最终返回的不再是字节,而是字节的数量,若返回-1,则表示没有更多数据。
public void readFile() throws IOException {
try (InputStream input = new FileInputStream("src/readme.txt")) {
// 定义1000个字节大小的缓冲区:
byte[] buffer = new byte[1000];
int n;
while ((n = input.read(buffer)) != -1) { // 读取到缓冲区
System.out.println("read " + n + " bytes.");
}
}
}
注意:在执行read方法时是阻塞的,因为不知道read方法j将会花费多长时间。
ByteArrayInputStream
ByteArrayInputSream,可以作为测试时使用的类,来创建InputStream
public class Main {
public static void main(String[] args) throws IOException {
byte[] data = { 72, 101, 108, 108, 111, 33 };
try (InputStream input = new ByteArrayInputStream(data)) {
String s = readAsString(input);
System.out.println(s);
}
}
public static String readAsString(InputStream input) throws IOException {
int n;
StringBuilder sb = new StringBuilder();
while ((n = input.read()) != -1) {
sb.append((char) n);
}
return sb.toString();
}
}