我有将文件复制到其他位置的代码。
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大小的文件时,它失败了。堆栈是:
运行: 12.01.2011 11:16:36 FileCopier主要 严重:复制文件时发生异常。再试一次。 java.io.IOException:映射失败 在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) 在FileCopier.copyFile(FileCopier.java:64) 在FileCopier.main(FileCopier.java:27) 引起:java.lang.OutOfMemoryError:映射失败 at sun.nio.ch.FileChannelImpl.map0(Native Method) at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:745) ......还有4个 建立成功(总时间:0秒)
我还没与NIO密切合作。你能帮帮我吗?非常感谢你。
答案 0 :(得分:5)
我想你可能已经被前一段时间遇到的old bug击中了。我没有尝试复制文件,而是寻找通过内存映射的文件,该文件也失败了。对我来说,解决方法是循环搜索文件并请求GC和finalizers不时运行。
内存映射的ByteBuffers
在终结器中释放它们的映射,并为新的映射腾出空间。这非常难看,但至少它有效。让我们希望他们在即将到来的NIO迭代中做到这一点。
答案 1 :(得分:2)
您是内存映射文件,但32位JVM(我认为您正在使用)中的内存地址空间有限,因此map方法失败。我认为你不能映射超过1.3-1.4 GB的磁盘数据。你使用的是什么堆大小?
您可以尝试减小堆大小或使用64位JRE。或者,不要使用NIO将文件映射到内存来读取文件。相反,使用缓冲读写器的传统方式从一个文件读取数据到另一个文件。