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

Reply via email to