/*** 目标:掌握字节缓冲流的作用*/
public class BufferedInputStreamTest1 {public static void main(String[] args){ try(InputStream is = new FileInputStream("D:/reSource/logo.png");// 1、定义一个字节缓冲输入流包装原始的字节输入流InputStream bis = new BufferedInputStream(is);OutputStream os = new FileOutputStream("C:/data/logo.png");// 2、定义一个字节缓冲输出流包换原始的字节输出流OutputStream bos = new BufferedOutputStream(os);){byte[] buffer = new byte[1024]; // 1KBint len; while ((len = bis.read(buffer)) != -1) {bos.write(buffer, 0, len);}System.out.println("复制完成");} catch (Exception e) {e.printStackTrace();} }
}
BufferedReader(字符缓冲输入流)
作用:自带8KB(8192字节)的字符缓冲池,可以提高字符输入流读取数据的性能
构造器
说明
Public BufferedReader(Reader r)
把低级的字符输入流包装成字符缓冲输入流管道
字符缓冲输入流新增的功能:按照行读取字符
方法
说明
Public String readLine()
读取一行数据返回,如果没有数据可读了,会返回null
/*** 目标:掌握字符缓冲输入流的用法*/
public class BufferedReaderTest2 {public static void main(String[] args) {try (Reader fr = new FileReader("src/ab.txt");// 创建一个字符缓冲输入流包装原始的字符输入流BufferedReader br = new BufferedReader(fr);) {// char[] buffer = new char[3];
// int len;
// while((len = fr.read(buffer)) != -1) {
// System.out.print(new String(buffer,0,len));
// }String line; // 记住每次读取的一行数据while((line = br.readLine()) != null) {System.out.println(line);}} catch (IOException e) {e.printStackTrace();}}
}
BufferedWriter(字符缓冲输出流)
作用:自带8KB(8192字节)的字符缓冲池,可以提高字符输出流写字符数据的性能
构造器
说明
Public BufferedWriter(Writer r)
把低级的字符输出流包装成一个高级的缓冲字符输出流管道,从而提高字符输出流写数据的性能
字符缓冲输出流新增的功能:换行
方法
说明
Public void newLine()
换行
public class BufferedWriterTest3 {public static void main(String[] args) {try (Writer fw = new FileWriter("src/out02.txt",true);// 创建一个字符缓冲输出流管道包装原始的字符输出流BufferedWriter bw = new BufferedWriter(fw);) {// 1、public void write(int c) : 写一个字符出去bw.write('a');bw.write(97);bw.write('叶'); // 写一个字符出去
// fw.write("\r\n");bw.newLine();// 2、public void write(String c) : 写一个字符串出去bw.write("我爱你中国abc");
// bw.write("\r\n");bw.newLine();} catch (IOException e) {e.printStackTrace();}}
}
案例:拷贝静夜思到另一个文件,恢复顺序
定义一个缓冲字符输入流管道与源文件接通
定义一个List集合存储读取的每行数据
定义一个循环按照行读取数据,存入到List集合中去
对List集合中的每行数据按照首字母编号升序排序
定义一个缓冲字符输出流管道与目标文件接通
遍历List集合中的每个元素,用缓冲字符输出管道写出来并换行
/*** 案例:拷贝静夜思到另一个文件,恢复顺序*/
public class Test4 {public static void main(String[] args) {try(// 1、定义一个缓冲字符输入流管道与源文件接通BufferedReader br = new BufferedReader(new FileReader("src/sort.txt"));// 5、创建一个缓冲字符输出流管道与目标文件接通BufferedWriter bw = new BufferedWriter(new FileWriter("src/Newsort.txt"));) {// 2、定义一个List集合存储读取的每一行ArrayList<String> data = new ArrayList<String>();// 3、按照行读取每段数据String line; // 记录读取的当前行while((line = br.readLine()) != null) {data.add(line);}// 4、对ArrayList集合中的每段进行排序,默认按照每段首字母编号排序Collections.sort(data);// 6、遍历List集合的每段内容,依次写出到新文件中for(String ln : data) {bw.write(ln); // 输出遍历的当前段落bw.newLine(); // 换行}} catch (Exception e) {e.printStackTrace();}}
}
原始流、缓冲流的性能分析
测试用例:
分别使用原始的字节流,以及字节缓冲流,赋值一个很大的视频文件
测试步骤:
使用低级的字节流按照一个一个字节的形式去复制文件
使用低级的字节流按照字节数组的形式复制文件
使用高级的缓冲字节流按照一个一个字节的形式复制文件
使用高级的缓冲字节流按照字节数组的形式复制文件
/*** 目标:观察原始流和缓冲流的性能*/
public class TimeTest4 {// 复制视频的路径private final static String SRC_FILE = "src/File1";// 复制到哪个目的地private final static String DEST_FILR = "D:\\";public static void main(String[] args) {
// copy01(); // 低级字节流一个一个字节的形式复制,非常慢,直接淘汰copy02(); // 低级字节流按照一个一个字节数组的形式复制,速度较慢copy03(); // 缓冲流按照一个一个字节的形式的复制,速度较慢copy04(); // 缓冲流按照一个一个字节数组的形式复制,速度极快,推荐使用!}private static void copy01() {long startTime = System.currentTimeMillis();try(InputStream is = new FileInputStream(SRC_FILE);OutputStream os = new FileOutputStream(DEST_FILR + "1.avi");) {int b;while((b = is.read()) != -1) {os.write(b);}} catch (Exception e) {e.printStackTrace();}long endTime = System.currentTimeMillis();System.out.println("低级字节流一个一个字节复制耗时:" + (endTime - startTime) / 1000.0 + "s");}private static void copy02() {long startTime = System.currentTimeMillis();try(InputStream is = new FileInputStream(SRC_FILE);OutputStream os = new FileOutputStream(DEST_FILR + "2.avi");) {byte[] buffer = new byte[1024]; // 1KBint len;while((len = is.read(buffer)) != -1) {os.write(buffer,0,len);}} catch (Exception e) {e.printStackTrace();}long endTime = System.currentTimeMillis();System.out.println("低级字节流使用字节数组复制耗时:" + (endTime - startTime) / 1000.0 + "s");}private static void copy03() {long startTime = System.currentTimeMillis();try(InputStream is = new FileInputStream(SRC_FILE);BufferedInputStream bis = new BufferedInputStream(is); OutputStream os = new FileOutputStream(DEST_FILR + "3.avi");BufferedOutputStream bos = new BufferedOutputStream(os);) {int b;while((b = bis.read()) != -1) {bos.write(b);}} catch (Exception e) {e.printStackTrace();}long endTime = System.currentTimeMillis();System.out.println("缓冲流一个一个字节复制耗时:" + (endTime - startTime) / 1000.0 + "s");}private static void copy04() {long startTime = System.currentTimeMillis();try(InputStream is = new FileInputStream(SRC_FILE);BufferedInputStream bis = new BufferedInputStream(is); OutputStream os = new FileOutputStream(DEST_FILR + "4.avi");BufferedOutputStream bos = new BufferedOutputStream(os);) {byte[] buffer = new byte[1024]; // 1KBint len;while((len = bis.read(buffer)) != -1) {bos.write(buffer,0,len);}} catch (Exception e) {e.printStackTrace();}long endTime = System.currentTimeMillis();System.out.println("缓冲流使用字节数组复制耗时:" + (endTime - startTime) / 1000.0 + "s"); }
}
3.IO——转换流
引出问题:不同编码读取时会乱码
字符输入转换流
字符输出抓换流
不同编码读取出现乱码的问题
如果代码编码和被读取的文本文件的编码是一致的,使用字符流读取文本文件时不会出现乱码!
如果代码编码和被读取的文本文件的编码是不一致的,使用字符流读取文本文件时就会出现乱码!
/*** 目标:掌握不同编码读取乱码的问题*/
public class Test1 {public static void main(String[] args) {try(// 1、创建一个文件字符输入流与源文件接通// 代码编码:UTF-8 文件的编码:UTF-8Reader fr = new FileReader("src/File1");// // 代码编码:UTF-8 文件的编码:GBK
// Reader fr = new FileReader("src/File1"); // 乱码// 2、把文件字符输入流包装成缓冲字符输入流BufferedReader br = new BufferedReader(fr);){String line;while((line = br.readLine()) != null) {System.out.println(line);}} catch (Exception e) {e.printStackTrace();}}
}