黑马程序员技术交流社区

标题: 写了个复制文件的改良代码,不足之处请指各位指出 [打印本页]

作者: abc784990536    时间: 2014-12-31 20:45
标题: 写了个复制文件的改良代码,不足之处请指各位指出
本帖最后由 abc784990536 于 2014-12-31 20:51 编辑

需求:使用带缓冲功能的字节流复制文件,判断路径及文件大小并选择复制方式。 思路

1、copyFile函数接收由调用者传递的两个参数(要复制的文件完整路径file和要复制到哪里的目录path)
2、创建file和path的实例对象,并进行一系列检测,避免复制后覆盖同名文件。并创建目标文件的完整路径。
3、检测完毕后就创建输入流和输出流。为了提高效率,加入缓冲技术。
4、(附加)显示一些格式化信息、记录程序执行时间等。
5、因为是字节流,所以不能使用读一行的方法,只能一次读一个字节,效率低,如果文件不是很大,
       可以建立一个数组,把输入流中的数据全部读到数组中,在把数组中的数据一次性写入输出流,
       但如果数据太大,会出现内存溢出,所以进行文件大小的判断,
       小于等于200MB用新增数组的方法,大于200MB用一次读一个方法,这样可以尽量提高效率。
6、复制完成,关闭资源





  1. package com.wgxin;

  2. import java.io.BufferedInputStream;
  3. import java.io.BufferedOutputStream;
  4. import java.io.File;
  5. import java.io.FileInputStream;
  6. import java.io.FileOutputStream;
  7. import java.io.IOException;
  8. import java.text.DecimalFormat;

  9. /**
  10. * 需求:使用带缓冲功能的字节流复制文件,判断路径及文件大小并选择复制方式。
  11. *
  12. * 思路:
  13. * 1、copyFile函数接收由调用者传递的两个参数(要复制的文件完整路径file和要复制到哪里的目录path)
  14. * 2、创建file和path的实例对象,并进行一系列检测,避免复制后覆盖同名文件。并创建目标文件的完整路径。
  15. * 3、检测完毕后就创建输入流和输出流。为了提高效率,加入缓冲技术。
  16. * 4、(附加)显示一些格式化信息、记录程序执行时间等。
  17. * 5、因为是字节流,所以不能使用读一行的方法,只能一次读一个字节,效率低,如果文件不是很大,
  18. *    可以建立一个数组,把输入流中的数据全部读到数组中,在把数组中的数据一次性写入输出流,
  19. *    但如果数据太大,会出现内存溢出,所以进行文件大小的判断,
  20. *    小于等于200MB用新增数组的方法,大于200MB用一次读一个方法,这样可以尽量提高效率。
  21. * 6、复制完成,关闭资源
  22. *
  23. * @author Administrator
  24. */
  25. public class CopyFile{
  26.         /**
  27.          * 复制文件
  28.          * @param file 需要复制文件的完整路径
  29.          * @param path 要复制到的目标目录
  30.          */
  31.         public static void copyFile(String file,String path){
  32.                 BufferedInputStream bis = null;
  33.                 BufferedOutputStream bos = null;
  34.                 try{
  35.                         File copyFile = new File(file);
  36.                         File savePath = new File(path);
  37.                         
  38.                         //如果要复制的文件不存在或者不是文件,发出提示并退出程序
  39.                         if (!(copyFile.exists() && copyFile.isFile())){
  40.                                 System.out.println("您指定要复制的文件不存在,请检查");
  41.                                 System.exit(0);
  42.                         }
  43.                         //如果要保存到的目录不存在,则创建该目录
  44.                         if (!(savePath.isDirectory())){
  45.                                 System.out.println("你指定存放复制后文件的目录不存在,将自动创建,然后继续复制文件");
  46.                                 savePath.mkdirs();
  47.                         }
  48.                         
  49.                         //创建目标文件完整路径。
  50.                         File saveFile = new File(savePath+"\\"+copyFile.getName());
  51.                         //如果saveFile是一个文件,说明有同名文件存在,则提示并退出程序,避免覆盖同名文件。
  52.                         if (saveFile.isFile()){
  53.                                 System.out.println("注意!该目录下有同名文件。复制文件失败!");
  54.                                 System.exit(0);
  55.                         }

  56.                         //创建输入流和输出流。
  57.                         bis = new BufferedInputStream(new FileInputStream(copyFile));
  58.                         bos = new BufferedOutputStream(new FileOutputStream(saveFile));

  59.                         //获取输入流中的的字节数。
  60.                         long len = bis.available();
  61.                         
  62.                         //格式化显示文件大小,保留1位小数
  63.                         DecimalFormat df = new DecimalFormat(".0");
  64.                         String size = null;
  65.                         if(len > 1024*1024*200){
  66.                                 System.out.println("要复制的文件超过200MB,复制缓慢,复制过程请勿关闭程序!");
  67.                         }else if(len > 1024*1024){
  68.                                 size = df.format(len/1024/1024) + " MB";
  69.                         }else if(len > 1024){
  70.                                 size = df.format(len/1024) + " KB";
  71.                         }else{
  72.                                 size = len + " 字节";
  73.                         }
  74.                         System.out.println("文件大小:" + size);
  75.                         System.out.println("复制中...");
  76.                         
  77.                         //记录复制开始时毫秒值
  78.                         long start = System.currentTimeMillis();
  79.                         
  80.                         //如果文件大于200MB,用一次读一个字节方式
  81.                         //否则就用数组一次性读取方式复制
  82.                         if(len > 1024*1024*200){
  83.                                 int by;
  84.                                 while((by=bis.read())!=-1){
  85.                                         bos.write(by);
  86.                                 }
  87.                         }else{
  88.                                 //创建数组缓冲区,指定大小为输入流中的的字节数len。
  89.                                 byte[] bytes = new byte[(int)len];               
  90.                                 bis.read(bytes);        //从输入流中读取所有数据存储到数组中。
  91.                                 bos.write(bytes);        //将数组中的所有数据写入的输出流缓冲区中。
  92.                         }
  93.                         //记录复制结束精辟时毫秒值
  94.                         long end = System.currentTimeMillis();
  95.                         
  96.                         System.out.println("复制完成");
  97.                         System.out.println("耗时:"+(end-start)+"毫秒");
  98.                 }
  99.                 catch(IOException e){
  100.                         throw new RuntimeException("复制文件失败");
  101.                 }
  102.                 //关闭流资源
  103.                 finally{
  104.                         try{
  105.                                 if (bis!=null){
  106.                                         bis.close();
  107.                                 }
  108.                         }
  109.                         catch(IOException e){
  110.                                 throw new RuntimeException("输入流关闭失败");
  111.                         }
  112.                         try{
  113.                                 if (bos!=null){
  114.                                         bos.close();
  115.                                 }
  116.                         }
  117.                         catch(IOException e){
  118.                                 throw new RuntimeException("输出流关闭失败");
  119.                         }
  120.                 }
  121.         }
  122.         
  123.         /**
  124.          * 主函数
  125.          *
  126.          */
  127.         <span style="background-color: rgb(255, 255, 255); line-height: 2.2em;">public static void main(String[] args){  </span>
复制代码






作者: abc784990536    时间: 2014-12-31 20:48
本帖最后由 abc784990536 于 2014-12-31 20:49 编辑

不知道什么原因,主函数一部分不见了,下面是主函数代码

public static void main(String[] args){  
        //源文件  
        String copyFile = "C:\\1.txt";  
         
        //指定目标路径,没有责创建  
        String savePath = "D:\\file";  
         
        copyFile(copyFile,savePath);  
    }  
}  




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2