2011-01-12 112 views
5

我有將文件複製到其他位置的代碼。嘗試複製大文件時出現NIO錯誤

public static void copyFile(String sourceDest, String newDest) throws IOException { 

    File sourceFile = new File(sourceDest); 
    File destFile = new File(newDest); 
    if (!destFile.exists()) { 
     destFile.createNewFile(); 
    } 

    FileChannel source = null; 
    FileChannel destination = null; 
    try { 
     source = new FileInputStream(sourceFile).getChannel(); 
     destination = new FileOutputStream(destFile).getChannel(); 
     destination.transferFrom(source, 0, source.size()); 
    } finally { 
     if (source != null) { 
      source.close(); 
     } 
     if (destination != null) { 
      destination.close(); 
     } 
    } 

} 
} 

雖然複製小塊,比如300-400 Mb,但一切都像魔術一樣工作。但是,當我試圖複製1.5 Gb大小的文件時,它失敗了。堆棧是:

run: 12.01.2011 11:16:36 FileCopier main SEVERE: Exception occured while copying file. Try again. java.io.IOException: Map failed at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:748) at sun.nio.ch.FileChannelImpl.transferFromFileChannel(FileChannelImpl.java:527) at sun.nio.ch.FileChannelImpl.transferFrom(FileChannelImpl.java:590) at FileCopier.copyFile(FileCopier.java:64) at FileCopier.main(FileCopier.java:27) Caused by: java.lang.OutOfMemoryError: Map failed at sun.nio.ch.FileChannelImpl.map0(Native Method) at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:745) ... 4 more BUILD SUCCESSFUL (total time: 0 seconds)

我沒有與NIO密切合作。你能幫我解決嗎?提前謝謝你。

+0

嘗試使用Files.copy http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/io/Files.html如果它有效,請在src中查看 – oluies 2011-01-12 08:28:17

+0

謝謝。但我寧願不在這個特定的情況下使用第三方庫。 – 2011-01-12 08:29:54

回答

5

我想你可能已經碰到了前一段已經遇到的old bug。我沒有試圖複製一個文件,而是試圖通過一個失敗的內存映射文件。對我來說,解決方法是在循環中查找文件並請求GCfinalizers每隔一段時間運行一次。

內存映射ByteBuffers在終結器中釋放它們的映射併爲新映射騰出空間。這非常醜陋,但至少它是有效的。讓我們希望他們在即將到來的NIO迭代中對此做了些什麼。

+1

我找到了解決方案。感謝您的洞察力。 http://snippets.dzone.com/posts/show/4946 – 2011-01-12 09:11:27

2

您是內存映射文件,但是在32位JVM(我推測您正在使用)中存在有限的內存地址空間,因此映射方法失敗。我不認爲你可以映射超過1.3-1.4 GB的磁盤數據。您使用的堆大小是多少?

您可以嘗試減少堆大小或使用64位JRE。或者,不要通過使用NIO將其映射到內存來讀取文件。相反,使用緩衝讀寫器的傳統方式來讀取和寫入一個文件中的數據。