概述

  • 为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组,缺省使用8192个字节(8Kb)的缓冲区。
  • 缓冲流要“套接”在相应的节点流之上,根据数据操作单位可以把缓冲流分为:

字节缓冲流:BufferedInputStream 和 BufferedOutputStream
字符缓冲流:BufferedReader 和 BufferedWriter

使用说明

  • 当读取数据时,数据按块读入缓冲区,其后的读操作则直接访问缓冲区
  • 当使用BufferedInputStream读取字节文件时,BufferedInputStream会一次性从文件中读取8192个字节(8Kb)存在缓冲区中,直到缓冲区装满了,才重新从文件中读取下一个8192个字节数组。
  • 向流中写入字节时,不会直接写到文件,先写到缓冲区中直到缓冲区写满, BufferedOutputStream才会把缓冲区中的数据一次性写到文件里。使用方法 flush()可以强制将缓冲区的内容全部写入输出流
  • 关闭流的顺序和打开流的顺序相反。只要关闭最外层流即可,关闭最外层流也会相应关闭内层节点流
  • flush()方法的使用:手动将buffer中内容写入文件
  • 如果是带缓冲区的流对象的close()方法,不但会关闭流,还会在关闭流之前刷新缓冲区,关闭后不能再写出

image.png


代码实现

  1. /*
  2. 字节缓冲流:BufferedInputStream 和 BufferedOutputStream实现非文本文件的复制
  3. */
  4. @Test
  5. public void BufferedStreamTest() throws FileNotFoundException {
  6. BufferedInputStream bis = null;
  7. BufferedOutputStream bos = null;
  8. try {
  9. //1.造文件
  10. File srcFile = new File("爱情与友情.jpg");
  11. File destFile = new File("爱情与友情3.jpg");
  12. //2.造流
  13. //2.1 造节点流
  14. FileInputStream fis = new FileInputStream((srcFile));
  15. FileOutputStream fos = new FileOutputStream(destFile);
  16. //2.2 造缓冲流
  17. bis = new BufferedInputStream(fis);
  18. bos = new BufferedOutputStream(fos);
  19. //3.复制的细节:读取、写入
  20. byte[] buffer = new byte[10];
  21. int len;
  22. while((len = bis.read(buffer)) != -1){
  23. bos.write(buffer,0,len);
  24. // bos.flush();//刷新缓冲区
  25. }
  26. } catch (IOException e) {
  27. e.printStackTrace();
  28. } finally {
  29. //4.资源关闭
  30. //要求:先关闭外层的流,再关闭内层的流
  31. if(bos != null){
  32. try {
  33. bos.close();
  34. } catch (IOException e) {
  35. e.printStackTrace();
  36. }
  37. }
  38. if(bis != null){
  39. try {
  40. bis.close();
  41. } catch (IOException e) {
  42. e.printStackTrace();
  43. }
  44. }
  45. //说明:关闭外层流的同时,内层流也会自动的进行关闭。关于内层流的关闭,我们可以省略.
  46. // fos.close();
  47. // fis.close();
  48. }
  49. }
  1. /*
  2. 使用字符缓冲流BufferedReader和BufferedWriter实现文本文件的复制
  3. */
  4. @Test
  5. public void testBufferedReaderBufferedWriter(){
  6. BufferedReader br = null;
  7. BufferedWriter bw = null;
  8. try {
  9. //创建文件和相应的流
  10. br = new BufferedReader(new FileReader(new File("dbcp.txt")));
  11. bw = new BufferedWriter(new FileWriter(new File("dbcp1.txt")));
  12. //读写操作
  13. //方式一:使用char[]数组
  14. // char[] cbuf = new char[1024];
  15. // int len;
  16. // while((len = br.read(cbuf)) != -1){
  17. // bw.write(cbuf,0,len);
  18. // // bw.flush();
  19. // }
  20. //方式二:使用String
  21. String data;
  22. while((data = br.readLine()) != null){
  23. //方法一:
  24. // bw.write(data + "\n");//data中不包含换行符
  25. //方法二:
  26. bw.write(data);//data中不包含换行符
  27. bw.newLine();//提供换行的操作
  28. }
  29. } catch (IOException e) {
  30. e.printStackTrace();
  31. } finally {
  32. //关闭资源
  33. if(bw != null){
  34. try {
  35. bw.close();
  36. } catch (IOException e) {
  37. e.printStackTrace();
  38. }
  39. }
  40. if(br != null){
  41. try {
  42. br.close();
  43. } catch (IOException e) {
  44. e.printStackTrace();
  45. }
  46. }
  47. }
  48. }
  49. }

练习题

  1. //取文本上每个字符出现的次数
  2. // 提示:遍历文本的每一个字符;字符及出现的次数保存在Map中;将Map中数据
  3. //写入文件
  4. public void test() {
  5. BufferedReader reader = null;
  6. BufferedWriter writer = null;
  7. try {
  8. reader = new BufferedReader(new FileReader("world.txt"));
  9. writer = new BufferedWriter(new FileWriter("count.txt"));
  10. Map<Character, Integer> save = new HashMap<>();
  11. int ch;
  12. while ((ch = reader.read()) != -1) {
  13. char key = (char) ch;
  14. if (save.get(key) != null) {
  15. save.put(key, save.get(key) + 1);
  16. } else {
  17. save.put(key, 1);
  18. }
  19. }
  20. Set<Map.Entry<Character, Integer>> entries = save.entrySet();
  21. Iterator<Map.Entry<Character, Integer>> iterator = entries.iterator();
  22. while (iterator.hasNext()) {
  23. Map.Entry<Character, Integer> next = iterator.next();
  24. Character key = next.getKey();
  25. Integer value = next.getValue();
  26. if ('\t' == key) {
  27. writer.write("Tab键" + "=" + value + "\n");
  28. } else if ('\n' == key) {
  29. writer.write("换行" + "=" + value + "\n");
  30. } else if ('\r' == key) {
  31. writer.write("回车" + "=" + value + "\n");
  32. } else if (' ' == key) {
  33. writer.write("空格" + "=" + value + "\n");
  34. } else {
  35. writer.write(key + "=" + value + "\n");
  36. }
  37. }
  38. } catch (IOException e) {
  39. e.printStackTrace();
  40. } finally {
  41. if (reader != null) {
  42. try {
  43. reader.close();
  44. } catch (IOException e) {
  45. e.printStackTrace();
  46. }
  47. }
  48. if (writer != null) {
  49. try {
  50. writer.close();
  51. } catch (IOException e) {
  52. e.printStackTrace();
  53. }
  54. }
  55. }
  56. }
  57. }