使用Java NIO可以更快地复制文件。我在互联网上找到了主要有两种方法来完成这个任务。
public static void copyFile(File sourceFile, File destinationFile) throws IOException {
if (!destinationFile.exists()) {
destinationFile.createNewFile();
}
FileChannel source = null;
FileChannel destination = null;
try {
source = new FileInputStream(sourceFile).getChannel();
destination = new FileOutputStream(destinationFile).getChannel();
destination.transferFrom(source, 0, source.size());
} finally {
if (source != null) {
source.close();
}
if (destination != null) {
destination.close();
}
}
}
在20个非常有用的Java代码片段中,我发现了一个不同的注释和技巧:
public static void fileCopy(File in, File out) throws IOException {
FileChannel inChannel = new FileInputStream(in).getChannel();
FileChannel outChannel = new FileOutputStream(out).getChannel();
try {
// inChannel.transferTo(0, inChannel.size(), outChannel); // original -- apparently has trouble copying large files on Windows
// magic number for Windows, (64Mb - 32Kb)
int maxCount = (64 * 1024 * 1024) - (32 * 1024);
long size = inChannel.size();
long position = 0;
while (position < size) {
position += inChannel.transferTo(position, maxCount, outChannel);
}
} finally {
if (inChannel != null) {
inChannel.close();
}
if (outChannel != null) {
outChannel.close();
}
}
}
但我没找到或理解什么是
"Windows的魔法数字,(64Mb-32Kb)"
它说inChannel.transferTo(0, inChannel.size(), outChannel)
在Windows上有问题,32768(=(64*1024*1024)-(32*1024))字节对于这种方法来说是最优的。
maxCount
减少? - Dante WWWWmaxCount
赋值为文件大小时才应该将其减少:maxCount = filesize
,然后在每个循环中递减它。 - Dante WWWWsize
不是剩余要转移的字节数。size
表示输入的结尾。position
的值需要不断前进,直到达到最大位置值size
。 因此,size
是position
可有的最大值,因为那时你已经到了文件的结尾。它是EOF位置。 它的值始终保持不变。我不确定我是否已经表述清楚。你说的是 - “不断朝着目标前进,并将目标同时向前移动”。这会重复计算你的进度。 - Ajoy BhatiaFileChannel::transferTo
的第二个参数确实是要传输的字节数,所以应该将其减少。然而,在这种情况下,你的代码仍然存在错误。while
循环的条件应该是while (size > 0)
,也就是说只要还有字节需要传输就继续循环。将起始点的值position
与还需传输的字节数进行比较是错误的。因此,while (position < size)
是错误的,因为一旦越过中间点,position > size
,所以while
循环就会退出。 - Ajoy Bhatia