Windows中大文件的FileChannel.transferTo [英] FileChannel.transferTo for large file in windows
问题描述
使用Java NIO可以更快地复制文件.我主要通过互联网发现了两种方法来完成这项工作.
Using Java NIO use can copy file faster. I found two kind of method mainly over internet to do this job.
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开发人员的Java代码段我发现了不同的注释和技巧:
In 20 very useful Java code snippets for Java Developers I found a different comment and trick:
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)"
"magic number for Windows, (64Mb - 32Kb)"
它表示inChannel.transferTo(0, inChannel.size(), outChannel)
在Windows中有问题,对于此方法而言,最佳值为32768(=(64 * 1024 * 1024)-(32 * 1024))字节.
It says that inChannel.transferTo(0, inChannel.size(), outChannel)
has problem in windows, is 32768 (= (64 * 1024 * 1024) - (32 * 1024)) byte is optimum for this method.
推荐答案
Windows对最大传输大小有硬性限制,如果超过该限制,则会出现运行时异常.因此,您需要进行调整.您提供的第二个版本是高级版本,因为它不假定通过一次transferTo()
调用就完全传输了文件,这与Javadoc一致.
Windows has a hard limit on the maximum transfer size, and if you exceed it you get a runtime exception. So you need to tune. The second version you give is superior because it doesn't assume the file was transferred completely with one transferTo()
call, which agrees with the Javadoc.
将传输大小设置为大于1MB几乎是没有意义的.
Setting the transfer size more than about 1MB is pretty pointless anyway.
编辑,您的第二个版本存在缺陷.您应将size
减少每次转移的金额.应该更像是:
EDIT Your second version has a flaw. You should decrement size
by the amount transferred each time. It should be more like:
while (position < size) {
long count = inChannel.transferTo(position, size, outChannel);
if (count > 0)
{
position += count;
size-= count;
}
}
这篇关于Windows中大文件的FileChannel.transferTo的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!