InputStream:InputStream 是 Java 标准库提供的基本的输入流。它位于 java.io 包里。 java.io 包提供了所有同步 IO 的功能。要特别注意的一点是, InputStream 并不是一个接口,而是一个抽象类,它是所有输入流的父类,InputSream实现了Closeable接口。
FileInputSream是InputStream类的子类,它实现了InputStream中的抽象方法read(),FileInputstream流被称为文件字节输入流,是指以文件字节输入流来读取数据。在读取数据时,若一个字节一个字节读取,效率会非常低下。
public class Demo01 {
public static void main(String[] args) {
InputStream in = null;
try {
// 创建(实例化)InputStream对象
in = new FileInputStream("d:\\IOTest\\demo.txt");
// 读操作
System.out.println((char)in.read());
System.out.println((char)in.read());
System.out.println((char)in.read());
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// 关闭流
try {
in.read();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
// 关闭抛异常,换为null
in = null;
}
}
}
}
所以使用到缓冲读取,利用缓冲区一次读取多个字节效率会高很多,父类InputStream提供了两种read()重载方法来读取多字节。如下:
// 一 读取若干字节到byte[]数组,返回读取字节数
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
// 二 指定byte[]数组偏移量和最大填充数
public int read(byte b[], int off, int len) throws IOException {
// .....
}
利用这两个方法读取多字节时,需要先定义一个byte[]数组做作为缓冲区,read()方法读取字节存到byte数组中,但不会超过byte数组大小,返回值是返回了读取的字节数,若返回值为-1则表示需要读取的文件已经没有数据了。
利用缓冲区一次读多个字节代码如下:
package com.apesource;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
public class Demo03 {
public static void main(String[] args) {
try (InputStream in = new FileInputStream("d:\\IOTest\\图片.jpg")) {
// 批量读取(缓冲)
byte[] buff = new byte[128];
// 每次读取若干字节,填充至buff字节数组中
// 使用循环遍历
int len = -1;
int count = 0;
while((len = in.read(buff)) != -1) {
System.out.println(String.format("第%d次,本次读取到%d个字节:%s", count++,len,Arrays.toString(buff)));
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
BufferedInputStream:作为缓冲输入流,它继承自FileInputStream,BufferedInputStream作用是为另一个输入流添加一些缓冲功能,BufferedInputStream本质是在内部定义了一个缓冲区数组buf[]实现的。
public class BufferedInputStream extends FilterInputStream {
protected volatile byte buf[];
}
在新建某个输入流对应的BufferedInputStream后,当我们调用read()方法时,它会分批将数据导入内部数组buf[],每次缓冲区数组的数据被读取完后,会继续调数据进缓冲区,从而提高读取效率。
缓冲区的数据存在于内存中,而原文件的数据存在硬盘或其他存储器中,当把硬盘或其他存储器中的数据通过BufferedInputstream缓冲输入流读取到缓冲区时,就是将数据从硬盘调到内存中,而内存的执行效率远比硬盘的效率要高,所以使用BufferedInputStream可以提高读取效率。
使用BufferedInputStream读取数据代码如下:
package com.apesource;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class Demo04 {
public static void main(String[] args) {
// 带有缓冲区的字节输入流
// 缓冲区默认大小为8192
// 带参数的BufferedInputStream对象
try (BufferedInputStream bu = new BufferedInputStream(new FileInputStream("d:\\IOTest\\图片.jpg"),8192)) {
// 从内存的buff缓冲区中读取一个字节
int data = -1;
while((data = bu.read()) != -1) {
System.out.println(data);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}