Java复制文件的四种方法之速度分析

Java复制文件的四种方法之速度分析

  • 1、使用字节流每次读取一个字节,再往目标文件写入
  • 2、使用字节流每次读取多个字节,再往目标文件写入
  • 3、使用缓冲流每次读取一个字节,再往目标文件写入
  • 4、使用缓冲流每次读取多个字节,再往目标文件写入

开门见山,使用最后一种方式,速度最快!

下面分别列出各种方法的代码,最后列出时间

字节流每次读取一个字节

/**
     * 使用字节流每次读取一个字节的方式进行拷贝
     *
     * @param path1 被拷贝的文件路径
     * @param path2 拷贝后的存放路径
     */
    public static void copy(String path1, String path2) {
        System.out.println("正在使用字节流每次读取一个字节的方式进行拷贝");
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(path1);
            fos = new FileOutputStream(path2);
            /*核心代码开始*/
            int b = -1;
            while ((b = fis.read()) != -1) {
                fos.write(b);
            }
            /*核心代码结束*/
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

字节流每次读取多个字节

/**
     * 使用字节流每次读取多个字节的方式进行拷贝
     *
     * @param path1 被拷贝的文件路径
     * @param path2 拷贝后的存放路径
     */
    public static void copy2(String path1, String path2) {
        System.out.println("正在使用字节流每次读取多个字节的方式进行拷贝");
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(path1);
            fos = new FileOutputStream(path2);
            /*核心代码开始*/
            byte[] buf = new byte[1024];
            int len = -1;
            while ((len = fis.read(buf)) != -1) {
                //读多个的,一定要以实际长度写入
                fos.write(buf, 0, len);
            }
            /*核心代码结束*/
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

缓冲流每次读取一个字节

/**
     * 使用缓冲流每次读取一个字节的方式进行拷贝
     *
     * @param path1 被拷贝的文件路径
     * @param path2 拷贝后的存放路径
     */
    public static void copy3(String path1, String path2) {
        System.out.println("正在使用缓冲流每次读取一个字节的方式进行拷贝");
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            bis = new BufferedInputStream(new FileInputStream(path1));
            bos = new BufferedOutputStream(new FileOutputStream(path2));
            /*核心代码开始*/
            int b = -1;
            while ((b = bis.read()) != -1) {
                bos.write(b);
            }
            /*核心代码结束*/
            bos.flush();//把此句写在上面的循环里和这里效果是不一样的,这样更快
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            try {
                if (bis != null) {
                    bis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (bos != null) {
                    bos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

缓冲流每次读取多个字节

/**
     * 使用缓冲流每次读取多个字节的方式进行拷贝
     *
     * @param path1 被拷贝的文件路径
     * @param path2 拷贝后的存放路径
     */
    public static void copy4(String path1, String path2) {
        System.out.println("正在使用缓冲流每次读取多个字节的方式进行拷贝");
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            bis = new BufferedInputStream(new FileInputStream(path1));
            bos = new BufferedOutputStream(new FileOutputStream(path2));
            /*核心代码开始*/
            int len = -1;
            byte[] buf = new byte[1024];
            while ((len = bis.read(buf)) != -1) {
                bos.write(buf, 0, len);
            }
            bos.flush(); //把此句写在上面的循环里和这里效果是不一样的,这样更快
            /*核心代码结束*/
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bis != null) {
                    bis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (bos != null) {
                    bos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
完整测试代码
package com.roohom.demo.ClassDemo.File.InputStream;

import java.io.*;

/**
 * ClassName: FileCopyBuffer
 * Author: Roohom
 * Site:github.com/roohom
 * Function:视频复制的四种方法:1.字节流每次读一个字节 2.字节流每次读多个字节 3.缓冲流一次读一个字节 4.缓冲流一次读多个字节
 * Date: 2020/7/30 17:05
 * Software: IntelliJ IDEA
 */
public class FileCopyBuffer {
    /**
     * 使用缓冲流每次读取多个字节的方式进行拷贝
     *
     * @param path1 被拷贝的文件路径
     * @param path2 拷贝后的存放路径
     */
    public static void copy4(String path1, String path2) {
        System.out.println("正在使用缓冲流每次读取多个字节的方式进行拷贝");
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            bis = new BufferedInputStream(new FileInputStream(path1));
            bos = new BufferedOutputStream(new FileOutputStream(path2));
            /*核心代码开始*/
            int len = -1;
            byte[] buf = new byte[1024];
            while ((len = bis.read(buf)) != -1) {
                bos.write(buf, 0, len);
            }
            bos.flush(); //把此句写在上面的循环里和这里效果是不一样的,这样更快
            /*核心代码结束*/
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bis != null) {
                    bis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (bos != null) {
                    bos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 使用缓冲流每次读取一个字节的方式进行拷贝
     *
     * @param path1 被拷贝的文件路径
     * @param path2 拷贝后的存放路径
     */
    public static void copy3(String path1, String path2) {
        System.out.println("正在使用缓冲流每次读取一个字节的方式进行拷贝");
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            bis = new BufferedInputStream(new FileInputStream(path1));
            bos = new BufferedOutputStream(new FileOutputStream(path2));
            /*核心代码开始*/
            int b = -1;
            while ((b = bis.read()) != -1) {
                bos.write(b);
            }
            /*核心代码结束*/
            bos.flush();//把此句写在上面的循环里和这里效果是不一样的,这样更快
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            try {
                if (bis != null) {
                    bis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (bos != null) {
                    bos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 使用字节流每次读取多个字节的方式进行拷贝
     *
     * @param path1 被拷贝的文件路径
     * @param path2 拷贝后的存放路径
     */
    public static void copy2(String path1, String path2) {
        System.out.println("正在使用字节流每次读取多个字节的方式进行拷贝");
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(path1);
            fos = new FileOutputStream(path2);
            /*核心代码开始*/
            byte[] buf = new byte[1024];
            int len = -1;
            while ((len = fis.read(buf)) != -1) {
                //读多个的,一定要以实际长度写入
                fos.write(buf, 0, len);
            }
            /*核心代码结束*/
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * 使用字节流每次读取一个字节的方式进行拷贝
     *
     * @param path1 被拷贝的文件路径
     * @param path2 拷贝后的存放路径
     */
    public static void copy(String path1, String path2) {
        System.out.println("正在使用字节流每次读取一个字节的方式进行拷贝");
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(path1);
            fos = new FileOutputStream(path2);
            /*核心代码开始*/
            int b = -1;
            while ((b = fis.read()) != -1) {
                fos.write(b);
            }
            /*核心代码结束*/
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        //path1 为被拷贝文件所在的路径
        String path1 = "D:\\动态桌面AE86.mp4";     //size:31.3 MB
        //path2 拷贝之后存放的路径
        String path2 = "D:\\copy\\";
        //rename 为你想命名的名字
        String rename = "AE86.mp4";
        path2 = path2 + rename;
        long start = System.currentTimeMillis();
        //copy(path1, path2);    //时间太长
        copy2(path1, path2);      // 204毫秒
//        copy3(path1,path2);    // 784毫秒
//        copy4(path1,path2);    // 56毫秒
        long end = System.currentTimeMillis();
        System.out.println("本次执行时间为:" + (end - start) + "毫秒");
    }
}

经过运行之后可以看到,使用第一种方式时间太长,让人等得捉急,一杯java(咖啡)回来,程序还没跑完。
使用第二种方式来进行拷贝,大概耗时200毫秒,
使用第三种方式大概耗时780毫秒,
使用第四种则最快,大概耗时56毫秒,而实际使用中还可以对默认的缓冲区大小进行自定义,来得到拷贝的最佳方案,得到尽可能的最短耗时。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值