Skip to content

Commit 63213c8

Browse files
author
Niall Pemberton
committed
Fix fir IO-175 IOUtils.doCopyFile() issues with very large files and closing file input streams - thanks to David Sitsky
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/io/trunk@723199 13f79535-47bb-0310-9956-ffa450edef68
1 parent ee8a7df commit 63213c8

2 files changed

Lines changed: 37 additions & 6 deletions

File tree

src/java/org/apache/commons/io/FileUtils.java

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ public FileUtils() {
9797
*/
9898
public static final long ONE_MB = ONE_KB * ONE_KB;
9999

100+
/**
101+
* The number of bytes in a 50 MB.
102+
*/
103+
private static final long FIFTY_MB = ONE_MB * 50;
104+
100105
/**
101106
* The number of bytes in a gigabyte.
102107
*/
@@ -671,16 +676,27 @@ private static void doCopyFile(File srcFile, File destFile, boolean preserveFile
671676
throw new IOException("Destination '" + destFile + "' exists but is a directory");
672677
}
673678

674-
FileChannel input = new FileInputStream(srcFile).getChannel();
679+
FileInputStream fis = null;
680+
FileOutputStream fos = null;
681+
FileChannel input = null;
682+
FileChannel output = null;
675683
try {
676-
FileChannel output = new FileOutputStream(destFile).getChannel();
677-
try {
678-
output.transferFrom(input, 0, input.size());
679-
} finally {
680-
IOUtils.closeQuietly(output);
684+
fis = new FileInputStream(srcFile);
685+
fos = new FileOutputStream(destFile);
686+
input = fis.getChannel();
687+
output = fos.getChannel();
688+
long size = input.size();
689+
long pos = 0;
690+
long count = 0;
691+
while (pos < size) {
692+
count = (size - pos) > FIFTY_MB ? FIFTY_MB : (size - pos);
693+
pos += output.transferFrom(input, pos, count);
681694
}
682695
} finally {
696+
IOUtils.closeQuietly(output);
697+
IOUtils.closeQuietly(fos);
683698
IOUtils.closeQuietly(input);
699+
IOUtils.closeQuietly(fis);
684700
}
685701

686702
if (srcFile.length() != destFile.length()) {

src/test/org/apache/commons/io/FileUtilsTestCase.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,21 @@ public void testCopyFile1() throws Exception {
643643
testFile1.lastModified() == destination.lastModified());*/
644644
}
645645

646+
public void IGNOREtestCopyFileLarge() throws Exception {
647+
648+
File largeFile = new File(getTestDirectory(), "large.txt");
649+
File destination = new File(getTestDirectory(), "copylarge.txt");
650+
651+
System.out.println("START: " + new java.util.Date());
652+
createFile(largeFile, FileUtils.ONE_GB);
653+
System.out.println("CREATED: " + new java.util.Date());
654+
FileUtils.copyFile(largeFile, destination);
655+
System.out.println("COPIED: " + new java.util.Date());
656+
657+
assertTrue("Check Exist", destination.exists());
658+
assertTrue("Check Full copy", destination.length() == largeFile.length());
659+
}
660+
646661
public void testCopyFile2() throws Exception {
647662
File destination = new File(getTestDirectory(), "copy2.txt");
648663

0 commit comments

Comments
 (0)