作为IO流的入门,今天我们将会见识到更强大的流。比如能够高效的读写缓冲流,能够转换编码的转换流,能够持久化存储对象的序列化流等等。这些功能更为强大的流,都在基本的流对象的基础之上创建而来的,就像穿上铠甲的武士一样,相当于是对基本流对象的一种增强。
1.1 概述
缓冲流也叫高效流,是对四个FileXxx流的增强,所以也是四个流,按照数据类型分类:
字节缓冲流:BufferedInputStream,BufferedOutputStream 字符缓冲流:BufferedReader,BufferedWriter
缓冲流的基本原理,是在创建流对象的时候,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO的次数,从而提高读写的效率。
——————————————————————————————————————
1.2 字节缓冲流
构造方法
public BufferedInputStream(InputStream in):创建一个新的缓冲输入流。 public BufferedOutputStream(OutputStream out):创建一个新的缓冲输出流。
//创建字节缓冲输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bis.txt"));
//创建字节缓冲输出流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bos.txt"));
效率测试
查询API,缓冲流的读写方法与基本的流是一致的,我们通过复制大文件,测试它的效率。 基本流,代码如下
private static void show1() throws IOException {
//记录开始时间
long start = System.currentTimeMillis();
//创建流对象
try (
FileInputStream fis = new FileInputStream("a.txt");
FileOutputStream fos = new FileOutputStream("aa.txt");
) {
//读写数据
int b;
while ((b = fis.read()) != -1) {
fos.write(b);
}
} catch (IOException e) {
e.printStackTrace();
}
//记录结束时间
long end = System.currentTimeMillis();
System.out.println("普通流复制时间:" + (end - start) + "毫秒");
}
private static void show2() {
//记录开始时间
long start = System.currentTimeMillis();
//创建流对象
try (
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("aa.txt"))
) {
//读写数据
int b;
while ((b = bis.read()) != -1) {
bos.write(b);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//记录结束时间
long end = System.currentTimeMillis();
System.out.println("缓冲流复制时间:" + (end - start) + "毫秒");
}
private static void show3() {
//记录开始时间
long start = System.currentTimeMillis();
//创建流对象
try (
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("aa.txt"));
) {
//读写数据
int len;
byte[] bytes = new byte[8 * 1024];
while ((len = bis.read(bytes)) != -1) {
bos.write(bytes, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//记录结束时间
long end = System.currentTimeMillis();
System.out.println("缓冲流使用数组赋值时间" + (end - start)+"毫秒");
}
——————————————————————————————————————
1.3字符缓冲流
构造方法
- public BufferedReader(Reader in):创建一个新的缓冲输入流
- public BufferedWriter(Writer out):创建一个新的缓冲输出流
//创建字符缓冲输入流
BufferedReader br=new BufferedReader(new FileReader("br.txt"));
//创建字符缓冲输出流
BufferedWriter bw=new BufferedWriter(new FileWriter("bw.txt"));
特有方法
字符缓冲流的基本方法与普通字符流的调用方式一致,不在阐述,我们来看看他们具备的特有的方法
- BufferedReader: public String readLine():读一行文字
- BufferedWriter: public void newLine():写一行行的分隔符,由系统属性定义分隔符
readLine方法演示,代码如下:
private static void show4() throws IOException {
//创建流对象
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
//定义字符串,保存读取的一行文字
String line = null;
//循环读取,读取到最后,返回null
while ((line = br.readLine()) != null) {
System.out.println(line);
System.out.println("-----------");
}
//释放资源
br.close();
}
newLine方法演示,代码如下:
private static void show5() throws IOException {
//创建流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("aa.txt"));
//写出数据
bw.write("黑马");
//写出换行
bw.newLine();
bw.write("程序员");
bw.close();
}
——————————————————————————————————————
1.4 练习:文本排序
请将文本信息恢复顺序:
案例分析
- 逐行读取文本信息
- 解析文本信息到集合中
- 遍历集合,按顺序,写出文本信息
案例实现
private static void show6() {
//创建map集合,保存文本数据,键为序号,值为文字
HashMap<String, String> lineMap = new HashMap<>();
//创建流对象
try (
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("aa.txt"));
) {
//读取数据
String line = null;
while ((line = br.readLine()) != null) {
//解析文本
String[] split=line.split("\\.");
lineMap.put(split[0], split[1]);
}
//遍历map集合
for (int i = 1; i <=lineMap.size(); i++) {
String key = String.valueOf(i);
//写出map中的文本
String value = lineMap.get(key);
//写出拼接文本
bw.write(key + "." + value);
//写出换行
bw.newLine();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}