为什么要使用缓冲流?缓冲流对文件复制速度有什么影响?

执键写春秋
• 阅读 1392

通过不使用缓冲流代码与使用缓冲流代码来对比测试一波:

package person.xsc.praticeIII;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Copy3 {
    public static void main(String[] args) throws FileNotFoundException{
        // TODO Auto-generated method stub         
         String srcPath="C:\\Users\\你是小朱老师呀\\Desktop\\JAVA编程.DOC";
         String destPath="C:\\Users\\你是小朱老师呀\\Desktop\\XSC\\test4.DOCX";
         //1.造源文件与目标文件
         File srcFile = new File(srcPath);
         File destFile = new File(destPath);
         //2.造节点流
         FileInputStream fis = new FileInputStream((srcFile));
         FileOutputStream fos = new FileOutputStream(destFile);  
         //文件大小
         long dataSize=srcFile.length();
         System.out.println("文件大小:" + dataSize + " B");
         //不使用缓冲流去复制
         long start0 = System.currentTimeMillis();
         byte[] byte0 = new byte[1024];
         int temp0 = 0 ;    
         try{
                while((temp0=fis.read(byte0))!=-1){    // 开始拷贝
                    fos.write(byte0,0,temp0) ;    // 边读边写
                }
                System.out.println("不使用缓冲流拷贝完成!") ;
            }catch(IOException e){
                e.printStackTrace() ;
                System.out.println("不使用缓冲流拷贝失败!") ;
            }
            try{
                fis.close() ;        // 关闭
                fos.close() ;        // 关闭
            }catch(IOException e){
                e.printStackTrace() ;
        }    
          long end0 = System.currentTimeMillis();
          //FileUtils.sizeOf(localFileCache)
          System.out.println("不使用缓冲流复制需要 " + (end0-start0) + " ms"+"复制速度为:" + dataSize / (end0-start0) + " B/ms");
          //使用缓冲流去复制
          BufferedInputStream bis = new BufferedInputStream(new FileInputStream((srcFile)));
          BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
          long start1 = System.currentTimeMillis();
          byte [] byte1 = new byte[1024];
          int temp1 = 0 ;    
          try{
                 while((temp1=bis.read(byte1))!=-1){    
                     bos.write(byte1,0,temp1) ;
                 }
                 System.out.println("使用缓冲流拷贝完成!") ;
             }catch(IOException e){
                 e.printStackTrace() ;
                 System.out.println("使用缓冲流拷贝失败!") ;
             }
             try{
                    fis.close() ;        // 关闭
                    fos.close() ;        // 关闭
                }catch(IOException e){
                    e.printStackTrace() ;
            }
           long end1 = System.currentTimeMillis();
           System.out.println("使用缓冲流复制需要 " + (end1-start1) + " ms"+"复制速度为:" + dataSize / (end1-start1) + " B/ms");
    }

}
输出:
文件大小:405504 B
不使用缓冲流拷贝完成!
不使用缓冲流复制需要 8 ms复制速度为:50688 B/ms
使用缓冲流拷贝完成!
使用缓冲流复制需要 2 ms复制速度为:202752 B/ms

通过上面程序运行结果发现:加入缓冲处理流的复制速度将有明显的提升。至于为什么复制速度会提升,是因为不带缓冲的复制操作,每读一个字节就要写入一个字节,由于涉及磁盘的IO操作相比内存的操作要慢很多,所以不带缓冲的流效率很低。带缓冲的流,可以一次读很多字节,但不向磁盘中写入,只是先放到内存里。等凑够了缓冲区大小的时候一次性写入磁盘,这种方式可以减少磁盘操作次数,速度就会提高很多!

点赞
收藏
评论区
推荐文章
Easter79 Easter79
3年前
tcp粘包与udp丢包的原因
tcp粘包与udp丢包的原因一,什么是tcp粘包与udp丢包TCP是面向流的, 流要说明就像河水一样, 只要有水, 就会一直流向低处, 不会间断. TCP为了提高传输效率, 发送数据的时候, 并不是直接发送数据到网路, 而是先暂存到系统缓冲, 超过时间或者缓冲满了, 才把缓冲区的内容发送
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
执键写春秋 执键写春秋
3年前
IO编程实例——使用缓冲流实现文件的拷贝
数据源:"C:\\Users\\你是小朱老师呀\\Desktop\\test.txt"数据的目的地:"C:\\Users\\你是小朱老师呀\\Desktop\\XSC\\test.txt"实现步骤:1.创建源文件与目标文件2.创建节点流3.创建缓冲流4.读取、写入5.释放packageperson.xsc.praticeIII;importjava.
Wesley13 Wesley13
3年前
Java IO输入输出
学前知道Java的IO使用“流”的概念来表示。IO流涉及到数据源和目的地。流,是从源“流向”目的的数据流。Java将各种数据源和目标之间数据的传输统一抽象为流,通过对流对象的操作来完成I/O功能。输入输出实际都是对内存而言的。数据源可以是键盘、文件、应用程序、鼠标、网络连接。
Wesley13 Wesley13
3年前
Java NIO和IO的区别
IO               NIO面向流           面向缓冲阻塞IO           非阻塞IO无               选择器面向流与面向缓冲JavaNIO和IO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的。JavaIO面向流意味着每次从流中
Wesley13 Wesley13
3年前
udp之关于linux udp收发包缓冲区大小
1、修订单个socket的缓冲区大小:通过setsockopt使用SO\_RCVBUF来设置接收缓冲区,该参数在设置的时候不会与rmem\_max进行对比校验,但是如果设置的大小超过rmem\_max的话,则超过rmem\_max的部分不会生效;2、修订linux系统udp缓冲区大小:通过rmem\_max来设置系统中udp缓存的上限,该值可通过如下方
Wesley13 Wesley13
3年前
Java.NIO编程一览笔录
Java标准IO与JavaNIO的简单差异示意: Java标准IOJavaNIOAPI调用简单复杂底层实现面向流(stream),单向面向通道(channel),释放CPU、内存压力成效同步阻塞同步非阻塞数据窥视阻塞读取,要么足够,要么没有使用缓冲区(Buffer),读数据时需要检查是否
Wesley13 Wesley13
3年前
KINECT内幕——解析SDK(MS SDK 2)
NUI图像数据流概述NUI的流数据是通过连续静态图像序列传递的。在上下文初始化阶段,应用程序将识别需要读取的流数据,并对其进行附加的流相关设置,包括数据解析度、图像类型、用于存储输入帧的缓冲区数量等内容。在应用程序检索并释放相关帧之前,如果运行时数据占满了缓冲区,那么系统将自动丢弃最旧的帧并重用缓冲区,也就是说,帧数据是可被丢弃的。同时系统最多允
Stella981 Stella981
3年前
Netty(七):流数据的传输处理
SocketBuffer的缺陷对于例如TCP/IP这种基于流的传输协议实现,接收到的数据会被存储在socket的接受缓冲区内。不幸的是,这种基于流的传输缓冲区并不是一个包队列,而是一个字节队列。这意味着,即使你以两个数据包的形式发送了两条消息,操作系统却不会把它们看成是两条消息,而仅仅是一个批次的字节序列。因此,在这种
Wesley13 Wesley13
3年前
JAVA NIO 直接缓冲区和非直接缓冲区
前面我们一直说NIO能够提高性能,那么到底如何提高效率。本篇就接着上一篇文章的缓冲区,来看看直接缓冲区和非直接缓冲区。非直接缓冲区首先看看非直接缓冲区。我们之前说过NIO通过通道连接磁盘文件与应用程序,通过缓冲区存取数据进行双向的数据传输。物理磁盘的存取是操作系统进行管理的,与物理磁盘的数据操作需要经过内核地址空间;而我们的Java应用