Java_IO_两种文件复制方式比较

来源:互联网 发布:电脑淘宝怎么看微淘 编辑:程序博客网 时间:2024/04/26 21:48

一:缓冲输入输出流(InputStream、OutputStream)

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:14px;">    /* 
  2.      *缓冲输入输出流方式复制文件  
  3.      */  
  4.     public static boolean copyFile(String srcFileName,String destFileName,boolean overlay){  
  5.             File srcFile = new File(srcFileName); //根据一个路径得到File对象  
  6.             //判断源文件是否存在  
  7.             if(!srcFile.exists()){  
  8.                 try{  
  9.                     throw new Exception("源文件:"+srcFileName+"不存在!");  
  10.                 }catch(Exception e){  
  11.                     e.printStackTrace();//将异常内容存到日志文件中  
  12.                 }  
  13.                 return false;  
  14.             }else if(!srcFile.isFile()){//判断是不是一个文件  
  15.                 try {  
  16.                     throw new Exception("复制文件失败,源文件:"+srcFileName+"不是一个文件!");  
  17.                 } catch (Exception e) {  
  18.                   
  19.                     e.printStackTrace();  
  20.                 }  
  21.                 return false;  
  22.                   
  23.             }  
  24.             //判断目标文件是否存在  
  25.             File destFile = new File(destFileName);//目标文件对象destFile  
  26.             if(destFile.exists()){  
  27.                 //如果目标文件存在并允许覆盖  
  28.                 if(overlay){  
  29.                     //删除已经存在的目标文件  
  30.                     new File(destFileName).delete();  
  31.                       
  32.                 }  
  33.             }else{  
  34.                 //如果目标文件所在目录不存在,则创建 目录  
  35.                 if(!destFile.getParentFile().exists()){  
  36.                     //目标文件所在目录不存在  
  37.                     //mkdirs():创建此抽象路径名指定的目录,包括所有必需但不存在的父目录  
  38.                     if(!destFile.getParentFile().mkdirs()){  
  39.                         //复制文件失败:创建目标文件所在目录失败  
  40.                         return false;  
  41.                     }  
  42.                 }  
  43.             }  
  44.               
  45.             //复制文件  
  46.             int byteread = 0;//读取的字节数  
  47.             InputStream  in = null;  
  48.             OutputStream  out = null;  
  49.               
  50.             try {  
  51.                 in  = new FileInputStream(srcFile);  
  52.                 out = new FileOutputStream(destFile);  
  53.                 byte[] buffer = new byte[1024];  
  54.                 /* 
  55.                  * 方法说明: 
  56.                  * ①:将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。 
  57.                  *      write(byte[] b, int off, int len)  
  58.                  *          b - 数据 
  59.                  *          off - 数据中的起始偏移量。 
  60.                  *          len - 要写入的字节数。  
  61.                  * ②:in.read(buffer))!=-1,是从流buffer中读取一个字节,当流结束的时候read返回-1 
  62.                  */  
  63.   
  64.                 while((byteread = in.read(buffer))!=-1){  
  65.                     out.write(buffer, 0, byteread);  
  66.                 }  
  67.                 return true;  
  68.             } catch (FileNotFoundException e) {  
  69.                   
  70.                 return false;  
  71.             } catch (IOException e) {  
  72.                 return false;  
  73.             }finally{  
  74.                 try {  
  75.                     if(out!=null){  
  76.                         out.close();  
  77.                     }  
  78.                     if(in!=null){  
  79.                         in.close();  
  80.                     }  
  81.                 } catch (IOException e) {  
  82.                       
  83.                     e.printStackTrace();  
  84.                 }  
  85.             }  
  86.     }</span>  

二:文件通道(FileChannel)

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:14px;">    /* 
  2.      * 使用文件通道的方式复制文件 
  3.      */  
  4.     public static void fileChannelCopy(String srcDirName,String destDirName){  
  5.         FileInputStream fi = null;  
  6.         FileOutputStream fo = null;  
  7.         FileChannel in = null;  
  8.         FileChannel out = null;  
  9.           
  10.         try {  
  11.             fi = new FileInputStream(new File(srcDirName));  
  12.             fo = new FileOutputStream( new File(destDirName));  
  13.             in = fi.getChannel();//得到对应的文件通道  
  14.             out = fo.getChannel();//得到对应的文件通道  
  15.             /* 
  16.              *       public abstract long transferTo(long position, long count, 
  17.                                          WritableByteChannel target)throws IOException; 
  18.              *          position - 文件中的位置,从此位置开始传输;必须为非负数   
  19.              *          count - 要传输的最大字节数;必须为非负数   
  20.              *          target - 目标通道    
  21.              *          返回:   
  22.                         实际已传输的字节数,可能为零   
  23.              */  
  24.             in.transferTo(0, in.size(), out);//连接两个通道,并且从in通道读取,然后写入out通道中  
  25.         } catch (FileNotFoundException e) {  
  26.           
  27.             e.printStackTrace();  
  28.         } catch (IOException e) {  
  29.           
  30.             e.printStackTrace();  
  31.         }finally{  
  32.             try {  
  33.                 fi.close();  
  34.                 in.close();  
  35.                 fo.close();  
  36.                 out.close();  
  37.             } catch (IOException e) {  
  38.                   
  39.                 e.printStackTrace();  
  40.             }  
  41.         }  
  42.           
  43.     }</span>  
测试上面的两个方法:
[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:14px;">public class copyFile{  
  2.     public static void main(String[] args) {  
  3.         String srcDirName = "E:/360cse_official.exe";//待复制的文件名  
  4.         String destDirName ="E:/360cse_official_test.exe";//目标文件名  
  5.         long start;  
  6.         long end;  
  7.         start = System.currentTimeMillis();//返回系统的当前时间  
  8.         copyFile.copyFile(srcDirName,destDirName,true);  
  9.         end = System.currentTimeMillis();  
  10.         System.out.println("缓冲输入输出流方式复制文件,用时:"+(end-start)+"ms");  
  11.           
  12.         start = System.currentTimeMillis();  
  13.         copyFile.fileChannelCopy(srcDirName,destDirName);  
  14.         end = System.currentTimeMillis();  
  15.         System.out.println("使用文件通道的方式复制文件,用时:"+(end-start)+"ms");  
  16.           
  17.     }</span>  
测试文件:

运行结果:
缓冲输入输出流方式复制文件,用时:499ms
使用文件通道的方式复制文件,用时:57ms

总结:

通过对上面两个方法测试,我们可以知道使用文件通道的方式复制文件,明显比输出流复制文件效率要高。
学到的知识点:
①:返回系统的当前时间:start = System.currentTimeMillis();
②:write(byte[] b, int off, int len) 方法
将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流
b - 数据
off - 数据中的起始偏移量。
len - 要写入的字节数。 
③:in.read(buffer))!=-1,是从流buffer中读取一个字节,当流结束的时候read返回-1
④:in.transferTo(0, in.size(), out);//连接两个通道,并且从in通道读取,然后写入out通道中

public abstract long transferTo(long position, long count,
            WritableByteChannel target)throws IOException;
position - 文件中的位置,从此位置开始传输;必须为非负数  
count - 要传输的最大字节数;必须为非负数  
target - 目标通道   
返回:  
实际已传输的字节数,可能为零  
0 0