zoukankan      html  css  js  c++  java
  • 字节流VS缓冲流

    ---恢复内容开始---

    字节流VS缓冲流

    java.io包中的类大致可以分为:InputStream、OutputStream、Reader、Writer。InputStream/Reader可以理解为input from数据源,OutputStream/Writer可以理解为output to数据目的地。他们的前者处理的是字节,后者处理的是字符。而数据源则可能是来自硬盘上的文件、内存中的变量、网络的数据等等。

    字节流:数据是以字节为单位进行读写操作

    缓冲流:将一个一个的字节先存入到缓冲区中
    在JVM中会开辟一块缓冲区的内存空间,然后将文件中的数据读取到缓冲区中,直到读满这个缓冲,才会将缓冲区中的数据获取到程序中。
    在JVM中会开辟一块缓冲区的内存空间,然后将程序中的数据写入到缓冲区中,直到写满这个缓冲,才会将缓冲区中的数据写入到文件中。

    缓冲流的原理:

    缓冲流作用是把数据先写入缓冲区,等缓冲区满了,再把数据写到文件里。这样效率就大大提高了。

     思考的问题:在一个只有一个人用网,网速稳定(10m)的完美情况下,怎样才能使下载速度达到5m/s的速度呢?或者是思考一下迅雷下载的原理。

    原理是这样的:你的电影是在服务器上下载的,迅雷会在他的服务器和你的客户端之间建立一个高速缓存器,并且实现一个进程多个线程的高速并发下载,即把你的电影二进制文件分段多线程下载,这样下载速度就上去了!

    注意的点:

    1.读文件的时候,也是一个字节地去读的,但是要直到读满这个这个缓冲才会将缓冲区的数据获取到程序中;

    2.写文件的时候,是将程序中的数据写入到缓冲区,直到写满这个缓冲区才会把缓冲区中的数据一次性写入到文件中。

    下面来比较一下字符流与缓冲流的运行速度:

     这是字符流:

    public class ByteDemo {
    
        public static void main(String[] args) {
            ByteDemo  bd=new ByteDemo();
            bd.copyFile("D:/Java/J2SE6.0 中文版API.chm",
                    "D:/Java/J2SE6.0 中文版APIty.chm");
        }
        public void copyFile(String path,String newpath){
            InputStream is = null ;
            OutputStream os;
            String str;
        
            try {
                long startTime = System.currentTimeMillis();// 获取开始的时间
                //实例化一个输入流对象
                 is = new FileInputStream(path);
                int size;
                try {
                    size = is.available();// 获取流中还能读取的字节数
                    // 创建数组
                    byte[] array = new byte[size];
       
                    // 开始读取文件中的数据
                    is.read(array);
                    str = new String(array);// 将字节数组转换为字符串
    
                    //System.out.println(str);
                
                    //实例化一个输出对象
                     os=new FileOutputStream(newpath);
                    os.write(array);
                    long endTime = System.currentTimeMillis();// 结束时间
    
                    System.out.println("查找玩所有的文件所需的时间是:" + (endTime - startTime) + "毫秒");
                } catch (IOException e) {
                    e.printStackTrace();
                }
                 
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            
        }
    
    }

    这是缓冲流:

    public class BufferedDemo {
    
        public static void main(String[] args) {
            BufferedDemo bd = new BufferedDemo();
            bd.copyFile("D:/Java/J2SE6.0 中文版API.chm",
                    "D:/Java/J2SE6.0 中文版APIty.chm");
        }
    
        /**
         * 拷贝文件的方法
         * 
         * @param path要拷贝的文件路径以及文件全名
         * @param newPath要存储的新文件路径以及完全全名
         */
        public void copyFile(String path, String newPath) {
            InputStream is = null;
            BufferedInputStream bis = null;
            OutputStream os = null;
            BufferedOutputStream bos = null;
            try {
                long startTime = System.currentTimeMillis();// 获取开始的时间
                // 实例化一个输入流的对象
                is = new FileInputStream(path);
                // 实例化一个缓冲输入流对象
                bis = new BufferedInputStream(is);
    
                int size = bis.available();// 获取流中还能读取的字节数
    
                // 创建数组
                byte[] array = new byte[size];
    
                // 开始读取文件中的数据
                bis.read(array);
    
                // System.out.println(new String(array));
    
                // 实例化一个输出流的对象
                os = new FileOutputStream(newPath);
                // 实例化一个缓冲输出流对象
                bos = new BufferedOutputStream(os);
    
                 bos.write(array);
    
                int in;
                while ((in = bis.read()) != -1) {
                    bos.write(in);
                }
    
                bos.flush();// 强制写入
                long endTime = System.currentTimeMillis();// 结束时间
    
                System.out.println("查找玩所有的文件所需的时间是:" + (endTime - startTime) + "毫秒");
    
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } 
    /*
    这一段代码的作用是:因为BufferedInputStream为别的输入流添加缓冲功能,在创建BufferedInputStream时会创建一个内部缓冲数组,
    用于缓冲数据,提高性能。默认的缓冲大小是8192个字节,如果你要读取的文件大于这个默认的大小时,缓冲区没有读满是不会被写入文件的。
    所以要关闭输入流,释放这个流的资源。或者用flush()这个命令强制写入。
    */
    finally { try { if (bos != null) bos.close(); if (os != null) os.close(); if (bis != null) bis.close(); if (is != null) is.close(); } catch (Exception e) { e.printStackTrace(); } } } }

    运行速度的对比:(578 字节大小的文件)

  • 相关阅读:
    html的URL参数传值问题
    html背景图片拉伸至全屏
    Laravel 用户验证Auth::attempt fail的问题
    HTML中meta的应用
    ubuntu升级php版本
    Laravel 目录结构分析
    css颜色渐变在不同浏览器的设置
    谷歌浏览器(Chrome)离线包的下载方法!
    RAD Studio 10 up1欢迎页证书不可用
    MySQL
  • 原文地址:https://www.cnblogs.com/java-7/p/5806775.html
Copyright © 2011-2022 走看看