您好,登錄后才能下訂單哦!
一、使用FileStreams復(fù)制
這是最經(jīng)典的方式將一個(gè)文件的內(nèi)容復(fù)制到另一個(gè)文件中。 使用FileInputStream讀取文件A的字節(jié),使用FileOutputStream寫入到文件B。 這是第一個(gè)方法的代碼:
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)) != -1) { output.write(buf, 0, bytesRead); } } finally { input.close(); output.close(); } }
正如你所看到的我們執(zhí)行幾個(gè)讀和寫操作try的數(shù)據(jù),所以這應(yīng)該是一個(gè)低效率的,下一個(gè)方法我們將看到新的方式。
二、使用FileChannel復(fù)制
Java NIO包括transferFrom方法,根據(jù)文檔應(yīng)該比文件流復(fù)制的速度更快。 這是第二種方法的代碼:
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(); } }
三、使用Commons IO復(fù)制
Apache Commons IO提供拷貝文件方法在其FileUtils類,可用于復(fù)制一個(gè)文件到另一個(gè)地方。它非常方便使用Apache Commons FileUtils類時(shí),您已經(jīng)使用您的項(xiàng)目?;旧?這個(gè)類使用Java NIO FileChannel內(nèi)部。 這是第三種方法的代碼:
private static void copyFileUsingApacheCommonsIO(File source, File dest) throws IOException { FileUtils.copyFile(source, dest); }
該方法的核心代碼如下:
private static void doCopyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException { if (destFile.exists() && destFile.isDirectory()) { throw new IOException("Destination '" + destFile + "' exists but is a directory"); } FileInputStream fis = null; FileOutputStream fos = null; FileChannel input = null; FileChannel output = null; try { fis = new FileInputStream(srcFile); fos = new FileOutputStream(destFile); input = fis.getChannel(); output = fos.getChannel(); long size = input.size(); long pos = 0; long count = 0; while (pos < size) { count = size - pos > FILE_COPY_BUFFER_SIZE ? FILE_COPY_BUFFER_SIZE : size - pos; pos += output.transferFrom(input, pos, count); } } finally { IOUtils.closeQuietly(output); IOUtils.closeQuietly(fos); IOUtils.closeQuietly(input); IOUtils.closeQuietly(fis); } if (srcFile.length() != destFile.length()) { throw new IOException("Failed to copy full contents from '" + srcFile + "' to '" + destFile + "'"); } if (preserveFileDate) { destFile.setLastModified(srcFile.lastModified()); } }
由此可見,使用Apache Commons IO復(fù)制文件的原理就是上述第二種方法:使用FileChannel復(fù)制
四、使用Java7的Files類復(fù)制
如果你有一些經(jīng)驗(yàn)在Java 7中你可能會(huì)知道,可以使用復(fù)制方法的Files類文件,從一個(gè)文件復(fù)制到另一個(gè)文件。 這是第四個(gè)方法的代碼:
private static void copyFileUsingJava7Files(File source, File dest) throws IOException { Files.copy(source.toPath(), dest.toPath()); }
五、測試
現(xiàn)在看到這些方法中的哪一個(gè)是更高效的,我們會(huì)復(fù)制一個(gè)大文件使用每一個(gè)在一個(gè)簡單的程序。 從緩存來避免任何性能明顯我們將使用四個(gè)不同的源文件和四種不同的目標(biāo)文件。 讓我們看一下代碼:
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.channels.FileChannel; import java.nio.file.Files; import org.apache.commons.io.FileUtils; public class CopyFilesExample { public static void main(String[] args) throws InterruptedException, IOException { File source = new File("C:\\Users\\nikos7\\Desktop\\files\\sourcefile1.txt"); File dest = new File("C:\\Users\\nikos7\\Desktop\\files\\destfile1.txt"); // copy file using FileStreamslong start = System.nanoTime(); long end; copyFileUsingFileStreams(source, dest); System.out.println("Time taken by FileStreams Copy = " + (System.nanoTime() - start)); // copy files using java.nio.FileChannelsource = new File("C:\\Users\\nikos7\\Desktop\\files\\sourcefile2.txt"); dest = new File("C:\\Users\\nikos7\\Desktop\\files\\destfile2.txt"); start = System.nanoTime(); copyFileUsingFileChannels(source, dest); end = System.nanoTime(); System.out.println("Time taken by FileChannels Copy = " + (end - start)); // copy file using Java 7 Files classsource = new File("C:\\Users\\nikos7\\Desktop\\files\\sourcefile3.txt"); dest = new File("C:\\Users\\nikos7\\Desktop\\files\\destfile3.txt"); start = System.nanoTime(); copyFileUsingJava7Files(source, dest); end = System.nanoTime(); System.out.println("Time taken by Java7 Files Copy = " + (end - start)); // copy files using apache commons iosource = new File("C:\\Users\\nikos7\\Desktop\\files\\sourcefile4.txt"); dest = new File("C:\\Users\\nikos7\\Desktop\\files\\destfile4.txt"); start = System.nanoTime(); copyFileUsingApacheCommonsIO(source, dest); end = System.nanoTime(); System.out.println("Time taken by Apache Commons IO Copy = " + (end - start)); } 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(); } } 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(); } } private static void copyFileUsingJava7Files(File source, File dest) throws IOException { Files.copy(source.toPath(), dest.toPath()); } private static void copyFileUsingApacheCommonsIO(File source, File dest) throws IOException { FileUtils.copyFile(source, dest); } }
輸出:
Time taken by FileStreams Copy = 127572360 Time taken by FileChannels Copy = 10449963 Time taken by Java7 Files Copy = 10808333 Time taken by Apache Commons IO Copy = 17971677
正如您可以看到的FileChannels拷貝大文件是最好的方法。如果你處理更大的文件,你會(huì)注意到一個(gè)更大的速度差。
以上就是java復(fù)制文件的4種方實(shí)例的詳細(xì)內(nèi)容,更多請關(guān)注億速云其它相關(guān)文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。