This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-io.git
The following commit(s) were added to refs/heads/master by this push: new 94aaf06 [IO-604] FileUtils.doCopyFile(File, File, boolean) can throw ClosedByInterruptException. 94aaf06 is described below commit 94aaf0649da33ad07a35c4dab29363227febce56 Author: Gary Gregory <gardgreg...@gmail.com> AuthorDate: Fri Apr 5 11:14:18 2019 -0400 [IO-604] FileUtils.doCopyFile(File, File, boolean) can throw ClosedByInterruptException. --- src/changes/changes.xml | 3 ++ src/main/java/org/apache/commons/io/FileUtils.java | 44 ++++++++++------------ 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index a024d10..7f4563b 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -89,6 +89,9 @@ The <action> type attribute can be add,update,fix,remove. <action issue="IO-594" dev="ggregory" type="add" due-to="Gary Gregory"> Add IOUtils copy methods with java.lang.Appendable as the target. </action> + <action issue="IO-604" dev="ggregory" type="fix" due-to="Gary Gregory"> + FileUtils.doCopyFile(File, File, boolean) can throw ClosedByInterruptException. + </action> </release> <release version="2.6" date="2017-10-15" description="Java 7 required, Java 9 supported."> diff --git a/src/main/java/org/apache/commons/io/FileUtils.java b/src/main/java/org/apache/commons/io/FileUtils.java index efbd3be..2089e67 100644 --- a/src/main/java/org/apache/commons/io/FileUtils.java +++ b/src/main/java/org/apache/commons/io/FileUtils.java @@ -35,6 +35,8 @@ import java.nio.channels.FileChannel; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; import java.util.ArrayList; import java.util.Collection; import java.util.Date; @@ -1107,7 +1109,7 @@ public class FileUtils { /** * Internal copy file method. - * This caches the original file length, and throws an IOException + * This uses the original file length, and throws an IOException * if the output file length is different from the current input file length. * So it may fail if the file changes size. * It may also fail with "IllegalArgumentException: Negative size" if the input file is truncated part way @@ -1128,32 +1130,24 @@ public class FileUtils { throw new IOException("Destination '" + destFile + "' exists but is a directory"); } - try (FileInputStream fis = new FileInputStream(srcFile); - FileChannel input = fis.getChannel(); - FileOutputStream fos = new FileOutputStream(destFile); - FileChannel output = fos.getChannel()) { - final long size = input.size(); // TODO See IO-386 - long pos = 0; - long count = 0; - while (pos < size) { - final long remain = size - pos; - count = remain > FILE_COPY_BUFFER_SIZE ? FILE_COPY_BUFFER_SIZE : remain; - final long bytesCopied = output.transferFrom(input, pos, count); - if (bytesCopied == 0) { // IO-385 - can happen if file is truncated after caching the size - break; // ensure we don't loop forever - } - pos += bytesCopied; - } - } + Path srcPath = srcFile.toPath(); + Path destPath = destFile.toPath(); + final long newLastModifed = preserveFileDate ? srcFile.lastModified() : destFile.lastModified(); + Files.copy(srcPath, destPath, StandardCopyOption.REPLACE_EXISTING); - final long srcLen = srcFile.length(); // TODO See IO-386 - final long dstLen = destFile.length(); // TODO See IO-386 + // TODO IO-386: Do we still need this check? + checkEqualSizes(srcFile, destFile, Files.size(srcPath), Files.size(destPath)); + // TODO IO-386: Do we still need this check? + checkEqualSizes(srcFile, destFile, srcFile.length(), destFile.length()); + + destFile.setLastModified(newLastModifed); + } + + private static void checkEqualSizes(final File srcFile, final File destFile, final long srcLen, final long dstLen) + throws IOException { if (srcLen != dstLen) { - throw new IOException("Failed to copy full contents from '" + - srcFile + "' to '" + destFile + "' Expected length: " + srcLen + " Actual: " + dstLen); - } - if (preserveFileDate) { - destFile.setLastModified(srcFile.lastModified()); + throw new IOException("Failed to copy full contents from '" + srcFile + "' to '" + destFile + + "' Expected length: " + srcLen + " Actual: " + dstLen); } }