处理流|缓冲流(Buffered)


缓冲流(字节型)实现非文本的复制

  • Buffered能够提高读写速度的原因:内部提供了一个缓冲区。
    打开源码,可以发现其内部提供了一个大小为1024八倍的常量,相当于提供了一个8192大小的缓冲区。当读文件时,先把文件读进缓冲区中,当达到8192大小时一次性写出。相应的也有一个flush()方法用来刷新缓冲区。(缓冲流的write中会自动进行flush刷新。)
    -

使用字节型缓冲流实现非文本文件(.MP4)的复制:

    @Test
    public void testCopyFile() {
        long start = System.currentTimeMillis();
        String srcPath = "video.mp4";
        String destPath = "video3.mp4";
        copyFileWithBuffered(srcPath, destPath);
        long end = System.currentTimeMillis();
        System.out.println("缓冲流(Buffered)复制文件花费的时间为:" + (end - start));
    }

    public void copyFileWithBuffered(String srcPath, String destPath) {
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            bis = new BufferedInputStream(new FileInputStream(new File(srcPath)));
            bos = new BufferedOutputStream(new FileOutputStream(new File(destPath)));
            //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 {
            //关闭外层流的同时,内层流也会自动进行关闭;可以省略内层流的关闭.
            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 testBufferedReaderBufferedWriter(){
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            br = new BufferedReader(new FileReader(new File("hello.txt")));
            bw = new BufferedWriter(new FileWriter(new File("hello2.txt")));
            //方式一:
//            char[] cbuf = new char[1024];
//            int len;
//            while ((len = br.read(cbuf)) != -1) {
//                bw.write(cbuf, 0, len);
//            }
            //方式二:
            String data;
            while((data=br.readLine())!=null){
                bw.write(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();
                }
            }
        }
    }

节点流与缓冲流总结

节点流(又称文件流) 缓冲流(处理流的一种)
FileInputStream (read(byte[] buffer)) BufferedInputStream (read(byte[] buffer))
FileOutputStream (write(byte[] buffer,0,len)) BufferedOutputStream (write(byte[] buffer,0,len))
FileReader (read(char[] cbuf)) BufferedReader (read(char[] cbuf)/readLine())
FileWriter (write(char[] cbuf,0,len)) BufferedWriter(write(char[] cbuf,0,len)/flush())

缓冲流练习1

需求:使用缓冲流实现图片加密解密操作。

异或加密:与其说这是一种加密算法,倒不如称其为文件信息的简单变换,将每一个数据与某给定数据进行异或操作即可完成加密或解密。

图片加密:

  @Test
    public void test1(){
        BufferedInputStream fis = null;
        BufferedOutputStream fos = null;
        try {
            fis = new BufferedInputStream(new FileInputStream("img1.jpg"));
            fos = new BufferedOutputStream(new FileOutputStream("img2.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();
                }
            }
        }
    }

图片解密:

  @Test
    public void test2(){
        BufferedInputStream fis = null;
        BufferedOutputStream fos = null;
        try {
            fis = new BufferedInputStream(new FileInputStream("img2.jpg"));
            fos = new BufferedOutputStream(new FileOutputStream("img3.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();
                }
            }
        }
    }

缓冲流练习2

获取文本上每个字符出现的次数。(提示:遍历文本的每一个字符,字符以及出现的次数保存在Map中;将Map中数据写入文件。)

 @Test
    public void test3(){
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            Map<Character, Integer> map = new HashMap<>();
            br = new BufferedReader(new FileReader("hello.txt"));
            bw = new BufferedWriter(new FileWriter("copyHello.txt"));
            int c = 0;
            while ((c = br.read()) != -1) {
                char ch = (char) c;
                if (map.get(ch) == null) {
                    map.put(ch, 1);
                } else {
                    map.put(ch, map.get(ch) + 1);
                }
            }
            Set<Map.Entry<Character, Integer>> entrySet = map.entrySet();
            for (Map.Entry<Character, Integer> i : entrySet) {
                switch (i.getKey()) {
                    case ' ':
                        bw.write("空格:" + i.getValue());
                        break;
                    case '\t':
                        bw.write("tab:" + i.getValue());
                        break;
                    case '\r':
                        bw.write("回车:" + i.getValue());
                        break;
                    case '\n':
                        bw.write("换行:" + i.getValue());
                        break;
                    default:
                        bw.write(i.getKey() + "=" + i.getValue());
                        break;
                }
                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();
                }
            }
        }
    }

在这里插入图片描述
程序执行后,写出到新文件中的内容如下:
在这里插入图片描述

发布了451 篇原创文章 · 获赞 1428 · 访问量 45万+

猜你喜欢

转载自blog.csdn.net/weixin_43691058/article/details/104921850