美文网首页
Java IO之缓冲流的使用

Java IO之缓冲流的使用

作者: 程序员汪汪 | 来源:发表于2021-04-04 23:36 被阅读0次

缓冲流涉及到的类

  • BufferedInputStream
  • BufferedOutputStream
  • BufferedReader
  • BufferedWriter

引入目的

  • 作用:提供流的读取、写入的速度
  • 提高读写速度的原因:内部提供了一个缓冲区。默认情况下是8kb

使用说明

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

使用BufferInputStream和BufferOutputStream实现非文本文件的复制

代码示例:

@Test
public void testBufferedStream() {

    BufferedOutputStream bos = null;
    BufferedInputStream bis = null;
    try {
        // 1.创建File对象,指定要复制的非文本文件
        File srcFile = new File("D:\\io\\test.jpg");
        File destFile = new File("D:\\io\\test_copy.jpg");

        // 2.创建节点流(字节流)
        FileInputStream fis = new FileInputStream(srcFile);
        FileOutputStream fos = new FileOutputStream(destFile);
        // 造缓冲流,可以合并书写
        //        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
        //        BufferedOutputStream bos = new BufferedOutputStream(new FilterOutputStream(destFile));
        bis = new BufferedInputStream(fis);
        bos = new BufferedOutputStream(fos);

        // 3.文件读取、写出操作
        byte[] buffer = new byte[1024];
        int len;
        while ((len = bis.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 4.关闭资源
        if (bos != null) {
            try {
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (bis != null) {
            try {
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

使用BufferedReader和BufferedWriter实现文本文件的复制

代码示例:

@Test
public void testBufferedReaderBufferWriter() {

    BufferedWriter bw = null;
    BufferedReader br = null;
    try {
        // 创建文件和响应的流
        br = new BufferedReader(new FileReader(new File("D:\\io\\hello.txt")));
        bw = new BufferedWriter(new FileWriter(new File("D:\\io\\hello_copy.txt")));

        // 读写操作
        // 方式一:使用char[]数组
        //            char[] cbuf = new char[1024];
        //            int len;
        //            while ((len = br.read(cbuf)) != -1) {
        //                bw.write(cbuf, 0, len);
        //                bw.flush();
        //            }

        // 方式二:使用String
        String data;
        while ((data = br.readLine()) != null) {
            // 方法一:
            //                bw.write(data + "\n"); // data中不包含换行符

            // 方法二:
            bw.write(data); // data中不包含换行符
            bw.newLine(); // 提供换行的操作
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 关闭资源
        if (bw != null) {
            try {
                bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (br != null) {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

小练习

测试缓冲流和节点流文件复制速度

节点流实现复制方法

//指定路径下文件的复制
public void copyFile(String srcPath, String destPath) {

    FileOutputStream fos = null;
    FileInputStream fis = null;
    try {
        // 1.根据给定路径创建File对象
        File srcFile = new File(srcPath);
        File destFile = new File(destPath);
        // 2.创建字节流
        fis = new FileInputStream(srcFile);
        fos = new FileOutputStream(destFile);
        // 3.开始复制
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer)) != -1) {
            fos.write(buffer, 0, len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (fos != null) {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (fis != null) {
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

缓冲流实现复制操作

//缓冲流实现文件复制的方法
public void copyFileWithBuffered(String srcPath, String destPath) {

    BufferedOutputStream bos = null;
    BufferedInputStream bis = null;
    try {
        // 1.根据传入的路径创建File实例
        File srcFile = new File(srcPath);
        File destFile = new File(destPath);

        // 2.创建节点流(字节流儿)
        FileInputStream fis = new FileInputStream(srcFile);
        FileOutputStream fos = new FileOutputStream(destFile);
        // 创建缓冲流
        bis = new BufferedInputStream(fis);
        bos = new BufferedOutputStream(fos);

        // 复制的相关操作
        byte[] buffer = new byte[1024];
        int len;
        while ((len = bis.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 4. 关闭资源
        if (bos != null) {
            try {
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (bis != null) {
            try {
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

测试二者速度

@Test
public void testCopyFileWithBuffered() {
    long start = System.currentTimeMillis();

    String srcPath = "D:\\io\\test.mp4";
    String destPath = "D:\\io\\test_copy.mp4";

    //        copyFile(srcPath, destPath); // 复制操作花费的时间为:29657 未使用缓冲流
    copyFileWithBuffered(srcPath, destPath); // 复制操作花费的时间为:9647 使用缓冲流

    long end = System.currentTimeMillis();

    System.out.println("复制操作花费的时间为:" + (end - start));
}

实现图片加密操作

加密操作

  • 将图片文件通过字节流读取到程序中
  • 将图片的字节流逐一进行^操作
  • 将处理后的图片字节流输出
//图片的加密
@Test
public void test1() {

    FileOutputStream fos = null;
    FileInputStream fis = null;
    try {
        fis = new FileInputStream("D:\\io\\test.jpg");
        fos = new FileOutputStream("D:\\io\\testSecret.jpg");

        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer)) != -1) {
            for (int i = 0; i < len; i++) {
                buffer[i] = (byte) (buffer[i] ^ 5);
            }
            fos.write(buffer, 0, len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (fos != null) {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (fis != null) {
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

解密操作

  • 将加密后图片文件通过字节流读取到程序中
  • 将图片的字节流逐一进行^操作(原理:A^B^B = A)
  • 将处理后的图片字节流输出
//图片的解密
@Test
public void test2() {

    FileOutputStream fos = null;
    FileInputStream fis = null;
    try {
        fis = new FileInputStream("D:\\io\\testSecret.jpg");
        fos = new FileOutputStream("D:\\io\\test1.jpg");

        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer)) != -1) {
            for (int i = 0; i < len; i++) {
                buffer[i] = (byte) (buffer[i] ^ 5);
            }
            fos.write(buffer, 0, len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (fos != null) {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (fis != null) {
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

统计文本字符出现次数

实现思路:

  1. 遍历文本每一个字符
  2. 字符出现的次数存在Map
  3. Map中的数据写入文件
@Test
public void testWordCount() {

    FileReader fr = null;
    BufferedWriter bw = null;
    try {
        // 1.创建Map集合
        Map<Character, Integer> map = new HashMap<>();
        // 2.遍历每一个字符,每个字符出现的次数放到map中
        fr = new FileReader("D:\\io\\hello.txt");
        int c = 0;
        while ((c = fr.read()) != -1) {
            // int 还原成 char
            char ch = (char) c;
            // 判断char是否在map中第一次出现
            if (map.get(ch) == null) {
                map.put(ch, 1);
            } else {
                map.put(ch, map.get(ch) + 1);
            }
        }

        // 3.把map中数据存在文件count.txt
        bw = new BufferedWriter(new FileWriter("D:\\io\\count.txt"));
        // 遍历map,再写入数据
        Set<Map.Entry<Character, Integer>> entrySet = map.entrySet();
        for (Map.Entry<Character, Integer> entry : entrySet) {
            switch (entry.getKey()) {
                case ' ':
                    bw.write("空格 = " + entry.getValue());
                    break;
                case '\t': // '\t'表示 tab键 制表符
                    bw.write("tab键 = " + entry.getValue());
                    break;
                case '\r': // '\r' 回车符
                    bw.write("回车 = " + entry.getValue());
                    break;
                case '\n':
                    bw.write("换行 = " + entry.getValue());
                    break;
                default:
                    bw.write(entry.getKey() + " = " + entry.getValue());
                    break;
            }
            bw.newLine();
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 4.关闭资源
        if (fr != null) {
            try {
                fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (bw != null) {
            try {
                bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

相关文章

  • Java IO之缓冲流的使用

    缓冲流涉及到的类 BufferedInputStream BufferedOutputStream Buffere...

  • 01Nio-Buffer

    缓冲区的使用 Java IO和NIO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的。 Java IO...

  • java-nio学习之java io比较

    java io 基本介绍 java nio和io区别 面向流与面向缓冲 IO是面向流的,NIO是面向缓冲区的。 J...

  • java使用io缓冲流

    首先明确java中的io流就是 input/output 在使用中有writer和read读写操作, 在使用中的步...

  • Java中的IO流

    Java中的IO流分类 输入IO流输入字节流(InputStream)处理流缓冲流(BufferedInputSt...

  • java基础之IO流

    IO流上:概述、字符流、缓冲区(java基础) IO流结构图 FilterInputStream、FilterOu...

  • IO和NIO区别

    IO是面向流的,NIO是面向缓冲区的;Java IO的各种流是阻塞的,Java NIO的非阻塞模式;Java NI...

  • Java之IO(四)缓冲流

    之前学习的字节流字符流,都可以读写文件对数据进行操作,当读写数据量很大时,读取的速度会很慢影响效率,那么Java中...

  • Java之IO流详解

    title: Java之IO流详解tags: Java IO流categories: Java IO流 大多数应用...

  • [java]13、缓冲流

    1、字节缓冲输出流 java.io.BufferedOutputStream extends OutputStre...

网友评论

      本文标题:Java IO之缓冲流的使用

      本文链接:https://www.haomeiwen.com/subject/mgzxkltx.html