Skip to content

Commit 034c7cc

Browse files
committed
[FS] Speed up LocalFile.copy() by using Java-NIO's Files.copy()
Using Files.copy() can be significantly faster than reading the content from a source InputStream and writing it to a target OutputStream. The only drawback of using using Files.copy() is that continuous progress reporting during the copy operation is not possible. For small files (which are copied in short time) this is not really a relevant and for large files the performance gain outweighs the loss of fine-grained progress information.
1 parent 33aba47 commit 034c7cc

File tree

3 files changed

+26
-1
lines changed

3 files changed

+26
-1
lines changed

resources/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/Messages.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public class Messages extends NLS {
3333
public static String failedCreateWrongType;
3434
public static String failedCreateAccessDenied;
3535
public static String failedMove;
36+
public static String failedCopy;
3637
public static String failedReadDuringWrite;
3738
public static String fileExists;
3839
public static String fileNotFound;

resources/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/local/LocalFile.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@
2727
import java.io.OutputStream;
2828
import java.net.URI;
2929
import java.nio.file.AccessDeniedException;
30+
import java.nio.file.CopyOption;
3031
import java.nio.file.DirectoryNotEmptyException;
3132
import java.nio.file.FileAlreadyExistsException;
3233
import java.nio.file.Files;
3334
import java.nio.file.NoSuchFileException;
35+
import java.nio.file.StandardCopyOption;
3436
import java.nio.file.StandardOpenOption;
3537
import org.eclipse.core.filesystem.EFS;
3638
import org.eclipse.core.filesystem.IFileInfo;
@@ -149,6 +151,27 @@ public void copy(IFileStore destFile, int options, IProgressMonitor monitor) thr
149151
super.copy(destFile, options, monitor);
150152
}
151153

154+
private static final CopyOption[] NO_OVERWRITE = {StandardCopyOption.COPY_ATTRIBUTES};
155+
private static final CopyOption[] OVERWRITE_EXISTING = {StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING};
156+
157+
@Override
158+
protected void copyFile(IFileInfo sourceInfo, IFileStore destination, int options, IProgressMonitor monitor) throws CoreException {
159+
if (destination instanceof LocalFile target) {
160+
try {
161+
boolean overwrite = (options & EFS.OVERWRITE) != 0;
162+
Files.copy(this.file.toPath(), target.file.toPath(), overwrite ? OVERWRITE_EXISTING : NO_OVERWRITE);
163+
} catch (FileAlreadyExistsException e) {
164+
Policy.error(EFS.ERROR_EXISTS, NLS.bind(Messages.fileExists, target.filePath), e);
165+
} catch (IOException e) {
166+
Policy.error(EFS.ERROR_WRITE, NLS.bind(Messages.failedCopy, this.filePath, target.filePath), e);
167+
} finally {
168+
IProgressMonitor.done(monitor);
169+
}
170+
} else {
171+
super.copyFile(sourceInfo, destination, options, monitor);
172+
}
173+
}
174+
152175
@Override
153176
public void delete(int options, IProgressMonitor monitor) throws CoreException {
154177
if (monitor == null)

resources/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/messages.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ deleteProblem = Problems encountered while deleting files.
2424
deleting = Deleting: {0}.
2525
failedCreateAccessDenied=Cannot create file, access denied: {0}.
2626
failedCreateWrongType=Cannot create file because existing file of wrong type exists: {0}.
27-
failedMove = Critical failure moving: {0} to: {1}. Content is lost.
27+
failedMove = Critical failure moving '{0}' to '{1}'. Content is lost.
28+
failedCopy = Could not copy file '{0}' to '{1}'.
2829
failedReadDuringWrite = Could not read from source when writing file: {0}
2930
fileExists = File already exists on disk: {0}.
3031
fileNotFound = File not found: {0}.

0 commit comments

Comments
 (0)