FileChannel.transferTo for large file in windows

Using Java NIO use can copy file faster. I found two kind of method mainly over internet to do this job. html

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(); } } }

In 20 very useful Java code snippets for Java Developers I found a different comment and trick: 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(); } } }

But I didn't find or understand what is meaning of windows

"magic number for Windows, (64Mb - 32Kb)" app

It says thatinChannel.transferTo(0, inChannel.size(), outChannel)has problem in windows, is 32768 (= (64 * 1024 * 1024) - (32 * 1024)) byte is optimum for this method. less

A: this

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. spa

Setting the transfer size more than about 1MB is pretty pointless anyway. .net

EDIT Your second version has a flaw. You should decrementmaxCountby the amount transferred each time. It should be more like: code

while (position < size) { long count = inChannel.transferTo(position, maxCount, outChannel); if (count > 0) { position += count; maxCount -= count; } }
相關文章
相關標籤/搜索