Skip to content

Commit f779562

Browse files
committed
[performance] IFile.create: reduce 1 of 3 store.fetchInfo()
Assume the file does not exist (normal case) - otherwise implementation fails later during actual write. #1443
1 parent b512a65 commit f779562

File tree

2 files changed

+34
-32
lines changed

2 files changed

+34
-32
lines changed

resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/FileSystemResourceManager.java

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.io.BufferedInputStream;
2424
import java.io.ByteArrayInputStream;
2525
import java.io.ByteArrayOutputStream;
26+
import java.io.FileNotFoundException;
2627
import java.io.IOException;
2728
import java.io.InputStream;
2829
import java.io.OutputStream;
@@ -1213,32 +1214,42 @@ public void write(IFile target, InputStream content, IFileInfo fileInfo, int upd
12131214
IFileStore store = getStore(target);
12141215
prepareWrite(target, fileInfo, updateFlags, append, targetResource, store);
12151216

1216-
// On Windows an attempt to open an output stream on a hidden file results in FileNotFoundException.
1217-
// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=194216
1218-
boolean restoreHiddenAttribute = false;
1219-
if (fileInfo.exists() && fileInfo.getAttribute(EFS.ATTRIBUTE_HIDDEN) && Platform.getOS().equals(Platform.OS_WIN32)) {
1220-
fileInfo.setAttribute(EFS.ATTRIBUTE_HIDDEN, false);
1221-
store.putInfo(fileInfo, EFS.SET_ATTRIBUTES, subMonitor.split(1));
1222-
restoreHiddenAttribute = true;
1223-
} else {
1224-
subMonitor.split(1);
1225-
}
12261217
int options = append ? EFS.APPEND : EFS.NONE;
1227-
try (OutputStream out = store.openOutputStream(options, subMonitor.split(1))) {
1228-
if (restoreHiddenAttribute) {
1229-
fileInfo.setAttribute(EFS.ATTRIBUTE_HIDDEN, true);
1218+
try {
1219+
boolean opened = false;
1220+
try (OutputStream out = store.openOutputStream(options, subMonitor.split(1))) {
1221+
opened = true;
1222+
FileUtil.transferStreams(content, out, store.toString(), subMonitor.split(1));
1223+
} catch (CoreException e) {
1224+
// On Windows an attempt to open an output stream on a hidden file results in
1225+
// FileNotFoundException.
1226+
// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=194216
1227+
if (opened || !(e.getCause() instanceof FileNotFoundException)
1228+
|| !Platform.getOS().equals(Platform.OS_WIN32)) {
1229+
throw e;
1230+
}
1231+
fileInfo = store.fetchInfo();
1232+
if (!(fileInfo.exists() && fileInfo.getAttribute(EFS.ATTRIBUTE_HIDDEN))) {
1233+
throw e;
1234+
}
1235+
// set hidden=false and retry:
1236+
fileInfo.setAttribute(EFS.ATTRIBUTE_HIDDEN, false);
12301237
store.putInfo(fileInfo, EFS.SET_ATTRIBUTES, subMonitor.split(1));
1231-
} else {
1232-
subMonitor.split(1);
1238+
try (OutputStream out = store.openOutputStream(options, null)) {
1239+
// restore Hidden Attribute:
1240+
fileInfo.setAttribute(EFS.ATTRIBUTE_HIDDEN, true);
1241+
store.putInfo(fileInfo, EFS.SET_ATTRIBUTES, subMonitor.split(1));
1242+
FileUtil.transferStreams(content, out, store.toString(), subMonitor.split(1));
1243+
}
12331244
}
1234-
FileUtil.transferStreams(content, out, store.toString(), subMonitor.split(1));
12351245
} catch (IOException e) {
1246+
// Exception on OutputStream.close()
12361247
String msg = NLS.bind(Messages.localstore_couldNotWrite, store.toString());
12371248
throw new ResourceException(IResourceStatus.FAILED_WRITE_LOCAL, IPath.fromOSString(store.toString()), msg, e);
12381249
}
12391250
finishWrite(targetResource, store);
12401251
} catch (IOException streamCloseIgnored) {
1241-
// ignore;
1252+
// ignore Exception on InputStream.close()
12421253
}
12431254
}
12441255

resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/File.java

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.eclipse.core.filesystem.EFS;
2525
import org.eclipse.core.filesystem.IFileInfo;
2626
import org.eclipse.core.filesystem.IFileStore;
27+
import org.eclipse.core.filesystem.provider.FileInfo;
2728
import org.eclipse.core.internal.preferences.EclipsePreferences;
2829
import org.eclipse.core.internal.utils.BitMask;
2930
import org.eclipse.core.internal.utils.Messages;
@@ -213,23 +214,13 @@ private void checkCreatable() throws CoreException {
213214
private IFileInfo create(int updateFlags, SubMonitor subMonitor, IFileStore store)
214215
throws CoreException, ResourceException {
215216
String message;
216-
IFileInfo localInfo = store.fetchInfo();
217+
IFileInfo localInfo;
217218
if (BitMask.isSet(updateFlags, IResource.FORCE)) {
218-
if (!Workspace.caseSensitive) {
219-
if (localInfo.exists()) {
220-
String name = getLocalManager().getLocalName(store);
221-
if (name == null || localInfo.getName().equals(name)) {
222-
delete(true, null);
223-
} else {
224-
// The file system is not case sensitive and there is already a file
225-
// under this location.
226-
message = NLS.bind(Messages.resources_existsLocalDifferentCase,
227-
IPath.fromOSString(store.toString()).removeLastSegments(1).append(name).toOSString());
228-
throw new ResourceException(IResourceStatus.CASE_VARIANT_EXISTS, getFullPath(), message, null);
229-
}
230-
}
231-
}
219+
// Assume the file does not exist - otherwise implementation fails later
220+
// during actual write
221+
localInfo = new FileInfo(getName()); // with exists==false
232222
} else {
223+
localInfo=store.fetchInfo();
233224
if (localInfo.exists()) {
234225
// return an appropriate error message for case variant collisions
235226
if (!Workspace.caseSensitive) {

0 commit comments

Comments
 (0)