From 247532bf34eee72656e118f235f3fa0b17482efb Mon Sep 17 00:00:00 2001 From: Mike Skells Date: Sun, 30 Oct 2011 14:53:43 +0000 Subject: [PATCH] 7103889: (fs) Reduce String concatenation when iterating over directory Reviewed-by: alanb --- .../share/classes/java/nio/file/Files.java | 18 ++++++++---- .../sun/nio/fs/WindowsDirectoryStream.java | 29 +++++++++++-------- .../classes/sun/nio/fs/WindowsPathParser.java | 12 ++++++-- 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/jdk/src/share/classes/java/nio/file/Files.java b/jdk/src/share/classes/java/nio/file/Files.java index 27778294000..2683b7efe09 100644 --- a/jdk/src/share/classes/java/nio/file/Files.java +++ b/jdk/src/share/classes/java/nio/file/Files.java @@ -363,6 +363,17 @@ public final class Files { // -- Directories -- + private static class AcceptAllFilter + implements DirectoryStream.Filter + { + private AcceptAllFilter() { } + + @Override + public boolean accept(Path entry) { return true; } + + static final AcceptAllFilter FILTER = new AcceptAllFilter(); + } + /** * Opens a directory, returning a {@link DirectoryStream} to iterate over * all entries in the directory. The elements returned by the directory @@ -397,12 +408,7 @@ public final class Files { public static DirectoryStream newDirectoryStream(Path dir) throws IOException { - return provider(dir).newDirectoryStream(dir, new DirectoryStream.Filter() { - @Override - public boolean accept(Path entry) { - return true; - } - }); + return provider(dir).newDirectoryStream(dir, AcceptAllFilter.FILTER); } /** diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java b/jdk/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java index 9a461f92c82..02309ff01b2 100644 --- a/jdk/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java @@ -124,26 +124,27 @@ class WindowsDirectoryStream private boolean atEof; private String first; private Path nextEntry; + private String prefix; WindowsDirectoryIterator(String first) { atEof = false; this.first = first; + if (dir.needsSlashWhenResolving()) { + prefix = dir.toString() + "\\"; + } else { + prefix = dir.toString(); + } + } + + // links to self and parent directories are ignored + private boolean isSelfOrParent(String name) { + return name.equals(".") || name.equals(".."); } // applies filter and also ignores "." and ".." private Path acceptEntry(String s, BasicFileAttributes attrs) { - if (s.equals(".") || s.equals("..")) - return null; - if (dir.needsSlashWhenResolving()) { - StringBuilder sb = new StringBuilder(dir.toString()); - sb.append('\\'); - sb.append(s); - s = sb.toString(); - } else { - s = dir + s; - } Path entry = WindowsPath - .createFromNormalizedPath(dir.getFileSystem(), s, attrs); + .createFromNormalizedPath(dir.getFileSystem(), prefix + s, attrs); try { if (filter.accept(entry)) return entry; @@ -157,7 +158,7 @@ class WindowsDirectoryStream private Path readNextEntry() { // handle first element returned by search if (first != null) { - nextEntry = acceptEntry(first, null); + nextEntry = isSelfOrParent(first) ? null : acceptEntry(first, null); first = null; if (nextEntry != null) return nextEntry; @@ -184,6 +185,10 @@ class WindowsDirectoryStream return null; } + // ignore link to self and parent directories + if (isSelfOrParent(name)) + continue; + // grab the attributes from the WIN32_FIND_DATA structure // (needs to be done while holding closeLock because close // will release the buffer) diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsPathParser.java b/jdk/src/windows/classes/sun/nio/fs/WindowsPathParser.java index f1158e5f7de..c45858b4ae9 100644 --- a/jdk/src/windows/classes/sun/nio/fs/WindowsPathParser.java +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsPathParser.java @@ -120,12 +120,18 @@ class WindowsPathParser { off = next; } else { if (isLetter(c0) && c1 == ':') { - root = input.substring(0, 2); - if (len > 2 && isSlash(input.charAt(2))) { + char c2; + if (len > 2 && isSlash(c2 = input.charAt(2))) { + // avoid concatenation when root is "D:\" + if (c2 == '\\') { + root = input.substring(0, 3); + } else { + root = input.substring(0, 2) + '\\'; + } off = 3; - root += "\\"; type = WindowsPathType.ABSOLUTE; } else { + root = input.substring(0, 2); off = 2; type = WindowsPathType.DRIVE_RELATIVE; }