https://www.bilibili.com/video/BV1ct411n7oG?p=182
装饰流也称为处理流。
字节缓冲流是对字节流的缓冲。
不管怎么套,最底层的一定是节点流。节点流始终处于第一线。
每个流都释放也没有问题,释放的规则是从里到外释放。
释放BufferedInputStream的时候,它内部会自己找要释放的节点流。
1、缓冲流提高了性能。
2、最底层的一定是节点流。节点流始终处于第一线。
3、释放的时候只需要释放最外层的处理流,它的内部会自动释放节点流。如果想手动地一个个释放,那原则是从里到外依次释放。
BufferedInputStream
为另一个输入流添加了功能,即缓冲输入。
BufferedInputStream
的缓冲区默认的是8K,可以自己指定:
BufferedOutputStream实现了缓冲输出流。
BufferedInputStream类的close方法源码:
public void close() throws IOException {
byte[] buffer;
while ( (buffer = buf) != null) {
if (U.compareAndSetReference(this, BUF_OFFSET, buffer, null)) {
InputStream input = in;
in = null;
if (input != null)
input.close();
return;
}
// Else retry in case a new buf was CASed in fill()
}
}
它要定位到最底层的节点流(变量in),然后调用其close方法,释放它的资源。
FileInputStream是通知操作系统(OS)释放资源。
BufferedInputStream是Java虚拟机(JVM)内部来维护一个内存大小的,然后虚拟机去通知垃圾回收机制来释放。
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class Test {
public static void main(String[] args) {
//1、创建源
File src = new File("abc.txt");
//2、选择流
InputStream is = null;
try {
is = new BufferedInputStream(new FileInputStream(src));
//3、操作(分段读取)
byte[] flush = new byte[1024];//缓冲容器
int len = -1;//接收长度
while((len = is.read(flush)) != -1) {
//字节数组-->字符串(解码)
String str = new String(flush, 0, len);
System.out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//4、释放资源
try {
if(null != is) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
输出结果:输出abc.txt里面的内容。
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class Test {
public static void main(String[] args) {
//1、创建源
File src = new File("dest.txt");
//2、选择流
OutputStream os = null;
try {
os = new BufferedOutputStream(new FileOutputStream(src));
//3、操作(写出)
String msg = "I LOVE JAVA!";
//字符串-->字节数组(编码)
byte[] datas = msg.getBytes();
os.write(datas, 0, datas.length);
os.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
//4、释放资源
try {
if(null != os) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
输出结果:创建文件dest.txt,里面写入 I LOVE JAVA!
对比性能:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Test {
public static void main(String[] args) {
long t1 = System.currentTimeMillis();
copy("CCTV新冠肺炎防疫公益广告《中国速度》.mp4", "copy.mp4");
long t2 = System.currentTimeMillis();
System.out.println(t2 - t1);
t1 = System.currentTimeMillis();
copy2("CCTV新冠肺炎防疫公益广告《中国速度》.mp4", "copy.mp4");
t2 = System.currentTimeMillis();
System.out.println(t2 - t1);
}
public static void copy(String srcPath, String destPsth) {
//1、创建源
File src = new File(srcPath);//源头
File dest = new File(destPsth);//目的地
//2、选择流
try(InputStream is = new FileInputStream(src);
OutputStream os = new FileOutputStream(dest);){
//3、操作(分段读取)
byte[] flush = new byte[1024];//缓冲容器
int len = -1;//接收长度
while((len = is.read(flush)) != -1) {
os.write(flush, 0, len);//分段写出
os.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 使用了缓冲流的文件拷贝方法
* @param srcPath
* @param destPsth
*/
public static void copy2(String srcPath, String destPsth) {
//1、创建源
File src = new File(srcPath);//源头
File dest = new File(destPsth);//目的地
//2、选择流
try(InputStream is = new BufferedInputStream(new FileInputStream(src));
OutputStream os = new BufferedOutputStream(new FileOutputStream(dest));){
//3、操作(分段读取)
byte[] flush = new byte[1024];//缓冲容器
int len = -1;//接收长度
while((len = is.read(flush)) != -1) {
os.write(flush, 0, len);//分段写出
os.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
输出结果:
325
184
可以看见,使用字节缓冲流,性能会有很大的提升,
但是不管多套几层new BufferedInputStream(new FileInputStream(src));new BufferedOutputStream(new FileOutputStream(dest));,它的内部只会提升一次。