java: 复制文件最快方法

利用Java复制文件到处都可以用到,这里总结了一个类供大家参考。里面总共有两个方法: 

public static boolean copyFile(String srcFileName, String destFileName,boolean overlay); 
public static boolean copyDirectory(String srcDirName, String destDirName,boolean overlay) ; 
其中: 
srcFileName 待复制的文件名 
descFileName  目标文件名 
overlay  如果目标文件存在,是否覆盖 
如果复制成功返回true,否则返回false 

代码:

    1.  import java.io.File;  
    2. import java.io.FileInputStream;  
    3. import java.io.FileNotFoundException;  
    4. import java.io.FileOutputStream;  
    5. import java.io.IOException;  
    6. import java.io.InputStream;  
    7. import java.io.OutputStream;  
    8.   
    9. import javax.swing.JOptionPane;  
    10.   
    11. /** 
    12.  * 复制文件或文件夹 
    13.  *  
    14.  * zww 
    15.  */  
    16. public class CopyFileUtil {  
    17.   
    18.     private static String MESSAGE = "";  
    19.   
    20.     /** 
    21.      * 复制单个文件 
    22.      *  
    23.      * @param srcFileName 
    24.      *            待复制的文件名 
    25.      * @param descFileName 
    26.      *            目标文件名 
    27.      * @param overlay 
    28.      *            如果目标文件存在,是否覆盖 
    29.      * @return 如果复制成功返回true,否则返回false 
    30.      */  
    31.     public static boolean copyFile(String srcFileName, String destFileName,  
    32.             boolean overlay) {  
    33.         File srcFile = new File(srcFileName);  
    34.   
    35.         // 判断源文件是否存在  
    36.         if (!srcFile.exists()) {  
    37.             MESSAGE = "源文件:" + srcFileName + "不存在!";  
    38.             JOptionPane.showMessageDialog(null, MESSAGE);  
    39.             return false;  
    40.         } else if (!srcFile.isFile()) {  
    41.             MESSAGE = "复制文件失败,源文件:" + srcFileName + "不是一个文件!";  
    42.             JOptionPane.showMessageDialog(null, MESSAGE);  
    43.             return false;  
    44.         }  
    45.   
    46.         // 判断目标文件是否存在  
    47.         File destFile = new File(destFileName);  
    48.         if (destFile.exists()) {  
    49.             // 如果目标文件存在并允许覆盖  
    50.             if (overlay) {  
    51.                 // 删除已经存在的目标文件,无论目标文件是目录还是单个文件  
    52.                 new File(destFileName).delete();  
    53.             }  
    54.         } else {  
    55.             // 如果目标文件所在目录不存在,则创建目录  
    56.             if (!destFile.getParentFile().exists()) {  
    57.                 // 目标文件所在目录不存在  
    58.                 if (!destFile.getParentFile().mkdirs()) {  
    59.                     // 复制文件失败:创建目标文件所在目录失败  
    60.                     return false;  
    61.                 }  
    62.             }  
    63.         }  
    64.   
    65.         // 复制文件  
    66.         int byteread = 0// 读取的字节数  
    67.         InputStream in = null;  
    68.         OutputStream out = null;  
    69.   
    70.         try {  
    71.             in = new FileInputStream(srcFile);  
    72.             out = new FileOutputStream(destFile);  
    73.             byte[] buffer = new byte[1024];  
    74.   
    75.             while ((byteread = in.read(buffer)) != -1) {  
    76.                 out.write(buffer, 0, byteread);  
    77.             }  
    78.             return true;  
    79.         } catch (FileNotFoundException e) {  
    80.             return false;  
    81.         } catch (IOException e) {  
    82.             return false;  
    83.         } finally {  
    84.             try {  
    85.                 if (out != null)  
    86.                     out.close();  
    87.                 if (in != null)  
    88.                     in.close();  
    89.             } catch (IOException e) {  
    90.                 e.printStackTrace();  
    91.             }  
    92.         }  
    93.     }  
    94.   
    95.     /** 
    96.      * 复制整个目录的内容 
    97.      *  
    98.      * @param srcDirName 
    99.      *            待复制目录的目录名 
    100.      * @param destDirName 
    101.      *            目标目录名 
    102.      * @param overlay 
    103.      *            如果目标目录存在,是否覆盖 
    104.      * @return 如果复制成功返回true,否则返回false 
    105.      */  
    106.     public static boolean copyDirectory(String srcDirName, String destDirName,  
    107.             boolean overlay) {  
    108.         // 判断源目录是否存在  
    109.         File srcDir = new File(srcDirName);  
    110.         if (!srcDir.exists()) {  
    111.             MESSAGE = "复制目录失败:源目录" + srcDirName + "不存在!";  
    112.             JOptionPane.showMessageDialog(null, MESSAGE);  
    113.             return false;  
    114.         } else if (!srcDir.isDirectory()) {  
    115.             MESSAGE = "复制目录失败:" + srcDirName + "不是目录!";  
    116.             JOptionPane.showMessageDialog(null, MESSAGE);  
    117.             return false;  
    118.         }  
    119.   
    120.         // 如果目标目录名不是以文件分隔符结尾,则加上文件分隔符  
    121.         if (!destDirName.endsWith(File.separator)) {  
    122.             destDirName = destDirName + File.separator;  
    123.         }  
    124.         File destDir = new File(destDirName);  
    125.         // 如果目标文件夹存在  
    126.         if (destDir.exists()) {  
    127.             // 如果允许覆盖则删除已存在的目标目录  
    128.             if (overlay) {  
    129.                 new File(destDirName).delete();  
    130.             } else {  
    131.                 MESSAGE = "复制目录失败:目的目录" + destDirName + "已存在!";  
    132.                 JOptionPane.showMessageDialog(null, MESSAGE);  
    133.                 return false;  
    134.             }  
    135.         } else {  
    136.             // 创建目的目录  
    137.             System.out.println("目的目录不存在,准备创建。。。");  
    138.             if (!destDir.mkdirs()) {  
    139.                 System.out.println("复制目录失败:创建目的目录失败!");  
    140.                 return false;  
    141.             }  
    142.         }  
    143.   
    144.         boolean flag = true;  
    145.         File[] files = srcDir.listFiles();  
    146.         for (int i = 0; i < files.length; i++) {  
    147.             // 复制文件  
    148.             if (files[i].isFile()) {  
    149.                 flag = CopyFileUtil.copyFile(files[i].getAbsolutePath(),  
    150.                         destDirName + files[i].getName(), overlay);  
    151.                 if (!flag)  
    152.                     break;  
    153.             } else if (files[i].isDirectory()) {  
    154.                 flag = CopyFileUtil.copyDirectory(files[i].getAbsolutePath(),  
    155.                         destDirName + files[i].getName(), overlay);  
    156.                 if (!flag)  
    157.                     break;  
    158.             }  
    159.         }  
    160.         if (!flag) {  
    161.             MESSAGE = "复制目录" + srcDirName + "至" + destDirName + "失败!";  
    162.             JOptionPane.showMessageDialog(null, MESSAGE);  
    163.             return false;  
    164.         } else {  
    165.             return true;  
    166.         }  
    167.     }  
    168.   
    169.     public static void main(String[] args) {  
    170.         String srcDirName = "C:/test/test0/test1";  
    171.         String destDirName = "c:/ttt";  
    172.         CopyFileUtil.copyDirectory(srcDirName, destDirName, true);  
    173.     }  
    174. }  

不考虑多线程优化,单线程文件复制最快的方法是(文件越大该方法越有优势,一般比常用方法快30+%):

  1. private static void nioTransferCopy(File source, File target) {  
  2.     FileChannel in = null;  
  3.     FileChannel out = null;  
  4.     FileInputStream inStream = null;  
  5.     FileOutputStream outStream = null;  
  6.     try {  
  7.         inStream = new FileInputStream(source);  
  8.         outStream = new FileOutputStream(target);  
  9.         in = inStream.getChannel();  
  10.         out = outStream.getChannel();  
  11.         in.transferTo(0, in.size(), out);  
  12.     } catch (IOException e) {  
  13.         e.printStackTrace();  
  14.     } finally {  
  15.         close(inStream);  
  16.         close(in);  
  17.         close(outStream);  
  18.         close(out);  
  19.     }  
  20. }  

如果需要监测复制进度,可以用第二快的方法(留意buffer的大小,对速度有很大影响):

  1. private static void nioBufferCopy(File source, File target) {  
  2.     FileChannel in = null;  
  3.     FileChannel out = null;  
  4.     FileInputStream inStream = null;  
  5.     FileOutputStream outStream = null;  
  6.     try {  
  7.         inStream = new FileInputStream(source);  
  8.         outStream = new FileOutputStream(target);  
  9.         in = inStream.getChannel();  
  10.         out = outStream.getChannel();  
  11.         ByteBuffer buffer = ByteBuffer.allocate(4096);  
  12.         while (in.read(buffer) != -1) {  
  13.             buffer.flip();  
  14.             out.write(buffer);  
  15.             buffer.clear();  
  16.         }  
  17.     } catch (IOException e) {  
  18.         e.printStackTrace();  
  19.     } finally {  
  20.         close(inStream);  
  21.         close(in);  
  22.         close(outStream);  
  23.         close(out);  
  24.     }  
  25. }  

常用的方法1是:

  1. private static void customBufferBufferedStreamCopy(File source, File target) {  
  2.     InputStream fis = null;  
  3.     OutputStream fos = null;  
  4.     try {  
  5.         fis = new BufferedInputStream(new FileInputStream(source));  
  6.         fos = new BufferedOutputStream(new FileOutputStream(target));  
  7.         byte[] buf = new byte[4096];  
  8.         int i;  
  9.         while ((i = fis.read(buf)) != -1) {  
  10.             fos.write(buf, 0, i);  
  11.         }  
  12.     }  
  13.     catch (Exception e) {  
  14.         e.printStackTrace();  
  15.     } finally {  
  16.         close(fis);  
  17.         close(fos);  
  18.     }  
  19. }  

常用的方法2是:

  1. private static void customBufferStreamCopy(File source, File target) {  
  2.     InputStream fis = null;  
  3.     OutputStream fos = null;  
  4.     try {  
  5.         fis = new FileInputStream(source);  
  6.         fos = new FileOutputStream(target);  
  7.         byte[] buf = new byte[4096];  
  8.         int i;  
  9.         while ((i = fis.read(buf)) != -1) {  
  10.             fos.write(buf, 0, i);  
  11.         }  
  12.     }  
  13.     catch (Exception e) {  
  14.         e.printStackTrace();  
  15.     } finally {  
  16.         close(fis);  
  17.         close(fos);  
  18.     }  
  19. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值