標籤:不同 from rom err nsf using [] 執行 bytes
一、使用FileStreams複製
這是最經典的方式將一個檔案的內容複寫到另一個檔案中。 使用FileInputStream讀取檔案A的位元組,使用FileOutputStream寫入到檔案B。 這是第一個方法的代碼:
1 private static void copyFileUsingFileStreams(File source, File dest) 2 throws IOException { 3 InputStream input = null; 4 OutputStream output = null; 5 try { 6 input = new FileInputStream(source); 7 output = new FileOutputStream(dest); 8 byte[] buf = new byte[1024]; 9 int bytesRead; 10 while ((bytesRead = input.read(buf)) != -1) {11 output.write(buf, 0, bytesRead);12 }13 } finally {14 input.close();15 output.close();16 }17 }
正如你所看到的我們執行幾個讀和寫操作try的資料,所以這應該是一個低效率的,下一個方法我們將看到新的方式。
二、使用FileChannel複製
Java NIO包括transferFrom方法,根據文檔應該比檔案流複製的速度更快。 這是第二種方法的代碼:
1 private static void copyFileUsingFileChannels(File source, File dest) throws IOException { 2 FileChannel inputChannel = null; 3 FileChannel outputChannel = null; 4 try { 5 inputChannel = new FileInputStream(source).getChannel(); 6 outputChannel = new FileOutputStream(dest).getChannel(); 7 outputChannel.transferFrom(inputChannel, 0, inputChannel.size()); 8 } finally { 9 inputChannel.close();10 outputChannel.close();11 }12 }
三、使用Commons IO複製
Apache Commons IO提供拷貝檔案方法在其FileUtils類,可用於複製一個檔案到另一個地方。它非常方便使用Apache Commons FileUtils類時,您已經使用您的項目。基本上,這個類使用Java NIO FileChannel內部。 這是第三種方法的代碼:
1 private static void copyFileUsingApacheCommonsIO(File source, File dest)2 throws IOException {3 FileUtils.copyFile(source, dest);4 }
該方法的核心代碼如下:
1 private static void doCopyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException { 2 if (destFile.exists() && destFile.isDirectory()) { 3 throw new IOException("Destination ‘" + destFile + "‘ exists but is a directory"); 4 } 5 6 FileInputStream fis = null; 7 FileOutputStream fos = null; 8 FileChannel input = null; 9 FileChannel output = null;10 try {11 fis = new FileInputStream(srcFile);12 fos = new FileOutputStream(destFile);13 input = fis.getChannel();14 output = fos.getChannel();15 long size = input.size();16 long pos = 0;17 long count = 0;18 while (pos < size) {19 count = size - pos > FILE_COPY_BUFFER_SIZE ? FILE_COPY_BUFFER_SIZE : size - pos;20 pos += output.transferFrom(input, pos, count);21 }22 } finally {23 IOUtils.closeQuietly(output);24 IOUtils.closeQuietly(fos);25 IOUtils.closeQuietly(input);26 IOUtils.closeQuietly(fis);27 }28 29 if (srcFile.length() != destFile.length()) {30 throw new IOException("Failed to copy full contents from ‘" +31 srcFile + "‘ to ‘" + destFile + "‘");32 }33 if (preserveFileDate) {34 destFile.setLastModified(srcFile.lastModified());35 }36 }
由此可見,使用Apache Commons IO複製檔案的原理就是上述第二種方法:使用FileChannel複製
四、使用Java7的Files類複製
如果你有一些經驗在Java 7中你可能會知道,可以使用複製方法的Files類檔案,從一個檔案複製到另一個檔案。 這是第四個方法的代碼:
1 private static void copyFileUsingJava7Files(File source, File dest)2 throws IOException { 3 Files.copy(source.toPath(), dest.toPath());4 }
五、測試
現在看到這些方法中的哪一個是更高效的,我們會複製一個大檔案使用每一個在一個簡單的程式。 從緩衝來避免任何效能明顯我們將使用四個不同的源檔案和四種不同的目標檔案。 讓我們看一下代碼:
1 import java.io.File; 2 import java.io.FileInputStream; 3 import java.io.FileOutputStream; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.io.OutputStream; 7 import java.nio.channels.FileChannel; 8 import java.nio.file.Files; 9 import org.apache.commons.io.FileUtils;10 11 public class CopyFilesExample {12 13 public static void main(String[] args) throws InterruptedException,14 IOException {15 16 File source = new File("C:\\Users\\nikos7\\Desktop\\files\\sourcefile1.txt");17 File dest = new File("C:\\Users\\nikos7\\Desktop\\files\\destfile1.txt");18 19 // copy file using FileStreamslong start = System.nanoTime();20 long end;21 copyFileUsingFileStreams(source, dest);22 System.out.println("Time taken by FileStreams Copy = "23 + (System.nanoTime() - start));24 25 // copy files using java.nio.FileChannelsource = new File("C:\\Users\\nikos7\\Desktop\\files\\sourcefile2.txt");26 dest = new File("C:\\Users\\nikos7\\Desktop\\files\\destfile2.txt");27 start = System.nanoTime();28 copyFileUsingFileChannels(source, dest);29 end = System.nanoTime();30 System.out.println("Time taken by FileChannels Copy = " + (end - start));31 32 // copy file using Java 7 Files classsource = new File("C:\\Users\\nikos7\\Desktop\\files\\sourcefile3.txt");33 dest = new File("C:\\Users\\nikos7\\Desktop\\files\\destfile3.txt");34 start = System.nanoTime();35 copyFileUsingJava7Files(source, dest);36 end = System.nanoTime();37 System.out.println("Time taken by Java7 Files Copy = " + (end - start));38 39 // copy files using apache commons iosource = new File("C:\\Users\\nikos7\\Desktop\\files\\sourcefile4.txt");40 dest = new File("C:\\Users\\nikos7\\Desktop\\files\\destfile4.txt");41 start = System.nanoTime();42 copyFileUsingApacheCommonsIO(source, dest);43 end = System.nanoTime();44 System.out.println("Time taken by Apache Commons IO Copy = "45 + (end - start));46 47 }48 49 private static void copyFileUsingFileStreams(File source, File dest)50 throws IOException {51 InputStream input = null;52 OutputStream output = null;53 try {54 input = new FileInputStream(source);55 output = new FileOutputStream(dest);56 byte[] buf = new byte[1024];57 int bytesRead;58 while ((bytesRead = input.read(buf)) > 0) {59 output.write(buf, 0, bytesRead);60 }61 } finally {62 input.close();63 output.close();64 }65 }66 67 private static void copyFileUsingFileChannels(File source, File dest)68 throws IOException {69 FileChannel inputChannel = null;70 FileChannel outputChannel = null;71 try {72 inputChannel = new FileInputStream(source).getChannel();73 outputChannel = new FileOutputStream(dest).getChannel();74 outputChannel.transferFrom(inputChannel, 0, inputChannel.size());75 } finally {76 inputChannel.close();77 outputChannel.close();78 }79 }80 81 private static void copyFileUsingJava7Files(File source, File dest)82 throws IOException {83 Files.copy(source.toPath(), dest.toPath());84 }85 86 private static void copyFileUsingApacheCommonsIO(File source, File dest)87 throws IOException {88 FileUtils.copyFile(source, dest);89 }90 91 }
輸出:
Time taken by FileStreams Copy = 127572360Time taken by FileChannels Copy = 10449963Time taken by Java7 Files Copy = 10808333Time taken by Apache Commons IO Copy = 17971677
正如您可以看到的FileChannels拷貝大檔案是最好的方法。如果你處理更大的檔案,你會注意到一個更大的速度差。 這是一個樣本,該樣本示範了Java中四種不同的方法可以複製一個檔案。
java複製檔案的4種方式