目录
5. 处理流之一:缓冲流
5.1 构造器
5.2 效率测试
5.3 字符缓冲流特有方法
5. 处理流之一:缓冲流
-
为了提高数据读写的速度
,Java API提供了带缓冲功能的流类:缓冲流。 -
缓冲流要“套接”在相应的节点流之上,根据数据操作单位可以把缓冲流分为:
-
字节缓冲流:
BufferedInputStream
,BufferedOutputStream
-
字符缓冲流:
BufferedReader
,BufferedWriter
-
-
缓冲流的基本原理:在创建流对象时,内部会创建一个缓冲区数组(缺省使用
8192个字节(8Kb)
的缓冲区),通过缓冲区读写,减少系统IO次数,从而提高读写的效率。
5.1 构造器
-
public BufferedInputStream(InputStream in)
:创建一个 新的字节型的缓冲输入流。 -
public BufferedOutputStream(OutputStream out)
: 创建一个新的字节型的缓冲输出流。
代码举例:
// 创建字节缓冲输入流 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("abc.jpg")); // 创建字节缓冲输出流 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("abc_copy.jpg"));
-
public BufferedReader(Reader in)
:创建一个 新的字符型的缓冲输入流。 -
public BufferedWriter(Writer out)
: 创建一个新的字符型的缓冲输出流。
代码举例:
// 创建字符缓冲输入流 BufferedReader br = new BufferedReader(new FileReader("br.txt")); // 创建字符缓冲输出流 BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"));
5.2 效率测试
查询API,缓冲流读写方法与基本的流是一致的,我们通过复制大文件(121MB),测试它的效率。
import org.junit.Test;
import java.io.*;
/**
* ClassName:IntelliJ IDEA
* Description:
* 测试FileInputStream + FileOutputStream 复制文件
* BufferedInputStream + BufferedOutputStream 复制文件
*
* 测试二者之间的效率。
*
* @Author zyjstart
* @Create:2024/10/15 15:14
*/
public class CopyFileTest {
@Test
public void testSpendTime(){
long start = System.currentTimeMillis();
String src = "C:\\Users\\奕佳\\Videos\\Captures\\新视频.mp4";
String dest = "E:\\tupian\\新视频copy1.mp4";
//copyFileWithFileStream(src,dest); //12439
copyDileWithBufferedStream(src,dest); //267
long end = System.currentTimeMillis();
System.out.println("花费的时间为:" + (end - start));
}
/**
* 使用BufferedInputStream + BufferedOutputStream 复制文件
*/
public void copyDileWithBufferedStream(String src,String dest){
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
//1、创建相关的File类的对象
File srcFile = new File(src);
File destFile = new File(dest);
//2、创建相关的字节流
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
//3、数据的读写操作
byte[] buffer = new byte[50];
int len; //记录每次读入到buffer中的字节数
while ((len = bis.read(buffer)) != -1){
bos.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4、关闭资源
try {
if (bis != null)
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (bos != null)
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 使用FileInputStream + FileOutputStream 复制文件
*/
public void copyFileWithFileStream(String src,String dest){
FileInputStream fis = null;
FileOutputStream fos = null;
try {
//1、创建相关的File类的对象
File srcFile = new File(src);
File destFile = new File(dest);
//2、创建相关的字节流
fis = new FileInputStream(srcFile);
fos = new FileOutputStream(destFile);
//3、数据的读写操作
byte[] buffer = new byte[50];
int len; //记录每次读入到buffer中的字节数
while ((len = fis.read(buffer)) != -1){
fos.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4、关闭资源
try {
if (fis != null)
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fos != null)
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行结果:
两个视频都复制过来了
花费的时间对比:
5.3 字符缓冲流特有方法
字符缓冲流的基本方法与普通字符流调用方式一致,不再阐述,我们来看它们具备的特有方法。
-
BufferedReader:
public String readLine()
: 读一行文字。 -
BufferedWriter:
public void newLine()
: 写一行行分隔符,由系统属性定义符号。
public class BufferedIOLine {
@Test
public void testReadLine()throws IOException {
// 创建流对象
BufferedReader br = new BufferedReader(new FileReader("in.txt"));
// 定义字符串,保存读取的一行文字
String line;
// 循环读取,读取到最后返回null
while ((line = br.readLine())!=null) {
System.out.println(line);
}
// 释放资源
br.close();
}
@Test
public void testNewLine()throws IOException{
// 创建流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("out.txt"));
// 写出数据
bw.write("尚");
// 写出换行
bw.newLine();
bw.write("硅");
bw.newLine();
bw.write("谷");
bw.newLine();
// 释放资源
bw.close();
}
}
说明:
涉及到嵌套的多个流时,如果都显式关闭的话,需要先关闭外层的流,再关闭内层的流
其实在开发中,只需要关闭最外层的流即可,因为在关闭外层流时,内层的流也会被关闭。