Skip to content

Commit

Permalink
[performance] IFile.create: reduce 1 of 3 store.fetchInfo()
Browse files Browse the repository at this point in the history
Assume the file does not exist (normal case) - otherwise implementation
fails later during actual write.

#1443
  • Loading branch information
EcljpseB0T authored and jukzi committed Jun 26, 2024
1 parent df1b825 commit 31f4f98
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
Expand Down Expand Up @@ -1213,32 +1214,42 @@ public void write(IFile target, InputStream content, IFileInfo fileInfo, int upd
IFileStore store = getStore(target);
prepareWrite(target, fileInfo, updateFlags, append, targetResource, store);

// On Windows an attempt to open an output stream on a hidden file results in FileNotFoundException.
// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=194216
boolean restoreHiddenAttribute = false;
if (fileInfo.exists() && fileInfo.getAttribute(EFS.ATTRIBUTE_HIDDEN) && Platform.getOS().equals(Platform.OS_WIN32)) {
fileInfo.setAttribute(EFS.ATTRIBUTE_HIDDEN, false);
store.putInfo(fileInfo, EFS.SET_ATTRIBUTES, subMonitor.split(1));
restoreHiddenAttribute = true;
} else {
subMonitor.split(1);
}
int options = append ? EFS.APPEND : EFS.NONE;
try (OutputStream out = store.openOutputStream(options, subMonitor.split(1))) {
if (restoreHiddenAttribute) {
fileInfo.setAttribute(EFS.ATTRIBUTE_HIDDEN, true);
try {
boolean opened = false;
try (OutputStream out = store.openOutputStream(options, subMonitor.split(1))) {
opened = true;
FileUtil.transferStreams(content, out, store.toString(), subMonitor.split(1));
} catch (CoreException e) {
// On Windows an attempt to open an output stream on a hidden file results in
// FileNotFoundException.
// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=194216
if (opened || !(e.getCause() instanceof FileNotFoundException)
|| !Platform.getOS().equals(Platform.OS_WIN32)) {
throw e;
}
fileInfo = store.fetchInfo();
if (!(fileInfo.exists() && fileInfo.getAttribute(EFS.ATTRIBUTE_HIDDEN))) {
throw e;
}
// set hidden=false and retry:
fileInfo.setAttribute(EFS.ATTRIBUTE_HIDDEN, false);
store.putInfo(fileInfo, EFS.SET_ATTRIBUTES, subMonitor.split(1));
} else {
subMonitor.split(1);
try (OutputStream out = store.openOutputStream(options, null)) {
// restore Hidden Attribute:
fileInfo.setAttribute(EFS.ATTRIBUTE_HIDDEN, true);
store.putInfo(fileInfo, EFS.SET_ATTRIBUTES, subMonitor.split(1));
FileUtil.transferStreams(content, out, store.toString(), subMonitor.split(1));
}
}
FileUtil.transferStreams(content, out, store.toString(), subMonitor.split(1));
} catch (IOException e) {
// Exception on OutputStream.close()
String msg = NLS.bind(Messages.localstore_couldNotWrite, store.toString());
throw new ResourceException(IResourceStatus.FAILED_WRITE_LOCAL, IPath.fromOSString(store.toString()), msg, e);
}
finishWrite(targetResource, store);
} catch (IOException streamCloseIgnored) {
// ignore;
// ignore Exception on InputStream.close()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.filesystem.provider.FileInfo;
import org.eclipse.core.internal.preferences.EclipsePreferences;
import org.eclipse.core.internal.utils.BitMask;
import org.eclipse.core.internal.utils.Messages;
Expand Down Expand Up @@ -213,23 +214,13 @@ private void checkCreatable() throws CoreException {
private IFileInfo create(int updateFlags, SubMonitor subMonitor, IFileStore store)
throws CoreException, ResourceException {
String message;
IFileInfo localInfo = store.fetchInfo();
IFileInfo localInfo;
if (BitMask.isSet(updateFlags, IResource.FORCE)) {
if (!Workspace.caseSensitive) {
if (localInfo.exists()) {
String name = getLocalManager().getLocalName(store);
if (name == null || localInfo.getName().equals(name)) {
delete(true, null);
} else {
// The file system is not case sensitive and there is already a file
// under this location.
message = NLS.bind(Messages.resources_existsLocalDifferentCase,
IPath.fromOSString(store.toString()).removeLastSegments(1).append(name).toOSString());
throw new ResourceException(IResourceStatus.CASE_VARIANT_EXISTS, getFullPath(), message, null);
}
}
}
// Assume the file does not exist - otherwise implementation fails later
// during actual write
localInfo = new FileInfo(getName()); // with exists==false
} else {
localInfo=store.fetchInfo();
if (localInfo.exists()) {
// return an appropriate error message for case variant collisions
if (!Workspace.caseSensitive) {
Expand Down

0 comments on commit 31f4f98

Please sign in to comment.