7168172: (fs) Files.isReadable slow on Windows
Summary: Remove DACL checking for read access, also reviewed by Ulf.Zibis@CoSoCo.de, zhong.j.yu@gmail.com
Reviewed-by: alanb
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java Fri Aug 24 19:35:30 2012 +0100
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java Fri Aug 24 11:48:51 2012 -0700
@@ -352,19 +352,34 @@
}
}
+ /**
+ * Checks if the given file(or directory) exists and is readable.
+ */
+ private void checkReadAccess(WindowsPath file) throws IOException {
+ try {
+ Set<OpenOption> opts = Collections.emptySet();
+ FileChannel fc = WindowsChannelFactory
+ .newFileChannel(file.getPathForWin32Calls(),
+ file.getPathForPermissionCheck(),
+ opts,
+ 0L);
+ fc.close();
+ } catch (WindowsException exc) {
+ // Windows errors are very inconsistent when the file is a directory
+ // (ERROR_PATH_NOT_FOUND returned for root directories for example)
+ // so we retry by attempting to open it as a directory.
+ try {
+ new WindowsDirectoryStream(file, null).close();
+ } catch (IOException ioe) {
+ // translate and throw original exception
+ exc.rethrowAsIOException(file);
+ }
+ }
+ }
+
@Override
public void checkAccess(Path obj, AccessMode... modes) throws IOException {
WindowsPath file = WindowsPath.toWindowsPath(obj);
- // if no access modes then simply file attributes
- if (modes.length == 0) {
- file.checkRead();
- try {
- WindowsFileAttributes.get(file, true);
- } catch (WindowsException exc) {
- exc.rethrowAsIOException(file);
- }
- return;
- }
boolean r = false;
boolean w = false;
@@ -378,6 +393,13 @@
}
}
+ // special-case read access to avoid needing to determine effective
+ // access to file; default if modes not specified
+ if (!w && !x) {
+ checkReadAccess(file);
+ return;
+ }
+
int mask = 0;
if (r) {
file.checkRead();