通道间的数据传输,java复制文件的4种方式10bet手机官网:
分类:web前端

 FileChannel类中有一方法transferFrom()可以方便完成文件的复制。详细介绍请查JDK文档。

在Java NIO中,如果两个通道中有一个是FileChannel,那你可以直接将数据从一个channel传输到另外一个channel。

RandomAccessFile fromFile =newRandomAccessFile("fromFile.txt","rw");

FileChannel      fromChannel = fromFile.getChannel();

RandomAccessFile toFile =newRandomAccessFile("toFile.txt","rw");

FileChannel      toChannel = toFile.getChannel();

longposition =0;

longcount = fromChannel.size();

toChannel.transferFrom(position, count, fromChannel);

方法的输入参数position表示从position处开始向目标文件写入数据,count表示最多传输的字节数。如果源通道的剩余空间小于 count 个字节,则所传输的字节数要小于请求的字节数。

RandomAccessFile fromFile =newRandomAccessFile("fromFile.txt","rw");

FileChannel      fromChannel = fromFile.getChannel();

RandomAccessFile toFile =newRandomAccessFile("toFile.txt","rw");

FileChannel      toChannel = toFile.getChannel();

long position =0;

long count = fromChannel.size();

fromChannel.transferTo(position, count, toChannel);

transferTo()方法将数据从FileChannel传输到其他的channel中

尽管Java提供了一个可以处理文件的IO操作类。 但是没有一个复制文件的方法。 复制文件是一个重要的操作,当你的程序必须处理很多文件相关的时候。 然而有几种方法可以进行Java文件复制操作,下面列举出4中最受欢迎的方式。

利用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

 据JDk文档上介绍说:“与从源通道读取并将内容写入此通道的简单循环语句相比,此方法可能高效得多。”

  1. 使用FileStreams复制

代码:

程序中如有用到文件复制的时候,用此方法试吧。

这是最经典的方式将一个文件的内容复制到另一个文件中。 使用FileInputStream读取文件A的字节,使用FileOutputStream写入到文件B。 这是第一个方法的代码:
private static void copyFileUsingFileStreams(File source, File dest)
        throws IOException {    
    InputStream input = null;    
    OutputStream output = null;    
    try {
           input = new FileInputStream(source);
           output = new FileOutputStream(dest);        
           byte[] buf = new byte[1024];        
           int bytesRead;        
           while ((bytesRead = input.read(buf)) > 0) {
               output.write(buf, 0, bytesRead);
           }
    } finally {
        input.close();
        output.close();
    }
}
正如你所看到的我们执行几个读和写操作try的数据,所以这应该是一个低效率的,下一个方法我们将看到新的方式。

  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.     }  

try {
    // 获得源文件的通道
    FileChannel srcChannel = new FileInputStream("srcFilename").getChannel();

  1. 使用FileChannel复制

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

    // 获得目的文件通道
    FileChannel dstChannel = new FileOutputStream("dstFilename").getChannel();

Java NIO包括transferFrom方法,根据文档应该比文件流复制的速度更快。 这是第二种方法的代码:
private static void copyFileUsingFileChannels(File source, File dest) throws IOException {    
        FileChannel inputChannel = null;    
        FileChannel outputChannel = null;    
    try {
        inputChannel = new FileInputStream(source).getChannel();
        outputChannel = new FileOutputStream(dest).getChannel();
        outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
    } finally {
        inputChannel.close();
        outputChannel.close();
    }
}

  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. }  

    // 将源文件内容复制到目的文件
    dstChannel.transferFrom(srcChannel, 0, srcChannel.size());

  1. 使用Commons IO复制

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

    // 关闭通道
    srcChannel.close();
    dstChannel.close();
} catch (IOException e) {
}

Apache Commons IO提供拷贝文件方法在其FileUtils类,可用于复制一个文件到另一个地方。它非常方便使用Apache Commons FileUtils类时,您已经使用您的项目。基本上,这个类使用Java NIO FileChannel内部。 这是第三种方法的代码:
private static void copyFileUsingApacheCommonsIO(File source, File dest)
        throws IOException {
    FileUtils.copyFile(source, dest);
}

  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. 使用Java7的Files类复制

常用的方法1是:

对应的,FileChannel类中也有transferTo()方法,从字面上可以猜知,该方法亦能完成文件的复制,只要这样即可:

如果你有一些经验在Java 7中你可能会知道,可以使用复制方法的Files类文件,从一个文件复制到另一个文件。 这是第四个方法的代码:
private static void copyFileUsingJava7Files(File source, File dest)
        throws IOException {    
        Files.copy(source.toPath(), dest.toPath());

  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. }  

srcChannel.transferTo(0, srcChannel.size(),dstChannel);

常用的方法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. }

感觉比在IO中使用繁琐的循环读写方便多了。Y(^_^)Y

本文由10bet手机官网发布于web前端,转载请注明出处:通道间的数据传输,java复制文件的4种方式10bet手机官网:

上一篇:没有了 下一篇:没有了
猜你喜欢
热门排行
精彩图文