7103889: (fs) Reduce String concatenation when iterating over directory
Reviewed-by: alanb
Contributed-by: mike.skells@talk21.com
--- a/jdk/src/share/classes/java/nio/file/Files.java Fri Oct 28 07:18:54 2011 -0700
+++ b/jdk/src/share/classes/java/nio/file/Files.java Sun Oct 30 14:53:43 2011 +0000
@@ -363,6 +363,17 @@
// -- Directories --
+ private static class AcceptAllFilter
+ implements DirectoryStream.Filter<Path>
+ {
+ 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 static DirectoryStream<Path> newDirectoryStream(Path dir)
throws IOException
{
- return provider(dir).newDirectoryStream(dir, new DirectoryStream.Filter<Path>() {
- @Override
- public boolean accept(Path entry) {
- return true;
- }
- });
+ return provider(dir).newDirectoryStream(dir, AcceptAllFilter.FILTER);
}
/**
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java Fri Oct 28 07:18:54 2011 -0700
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java Sun Oct 30 14:53:43 2011 +0000
@@ -124,26 +124,27 @@
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 @@
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 @@
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)
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsPathParser.java Fri Oct 28 07:18:54 2011 -0700
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsPathParser.java Sun Oct 30 14:53:43 2011 +0000
@@ -120,12 +120,18 @@
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;
}