Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
5091708e
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
5091708e
编写于
4月 23, 2013
作者:
A
alanb
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8012930: (fs) Eliminate recursion from FileTreeWalker
Reviewed-by: chegar
上级
92e32815
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
513 addition
and
190 deletion
+513
-190
src/share/classes/java/nio/file/FileTreeWalker.java
src/share/classes/java/nio/file/FileTreeWalker.java
+308
-143
src/share/classes/java/nio/file/Files.java
src/share/classes/java/nio/file/Files.java
+54
-1
test/java/nio/file/Files/walkFileTree/CreateFileTree.java
test/java/nio/file/Files/walkFileTree/CreateFileTree.java
+34
-15
test/java/nio/file/Files/walkFileTree/MaxDepth.java
test/java/nio/file/Files/walkFileTree/MaxDepth.java
+8
-5
test/java/nio/file/Files/walkFileTree/SkipSiblings.java
test/java/nio/file/Files/walkFileTree/SkipSiblings.java
+13
-6
test/java/nio/file/Files/walkFileTree/SkipSubtree.java
test/java/nio/file/Files/walkFileTree/SkipSubtree.java
+85
-0
test/java/nio/file/Files/walkFileTree/TerminateWalk.java
test/java/nio/file/Files/walkFileTree/TerminateWalk.java
+8
-5
test/java/nio/file/Files/walkFileTree/find.sh
test/java/nio/file/Files/walkFileTree/find.sh
+3
-15
未找到文件。
src/share/classes/java/nio/file/FileTreeWalker.java
浏览文件 @
5091708e
...
...
@@ -25,27 +25,147 @@
package
java.nio.file
;
import
java.nio.file.attribute.*
;
import
java.nio.file.attribute.BasicFileAttributes
;
import
java.io.Closeable
;
import
java.io.IOException
;
import
java.util.*
;
import
java.util.ArrayDeque
;
import
java.util.Iterator
;
import
java.util.Set
;
import
sun.nio.fs.BasicFileAttributesHolder
;
/**
* Simple file tree walker that works in a similar manner to nftw(3C).
* Walks a file tree, generating a sequence of events corresponding to the files
* in the tree.
*
* <pre>{@code
* Path top = ...
* Set<FileVisitOption> options = ...
* int maxDepth = ...
*
* try (FileTreeWalker walker = new FileTreeWalker(options, maxDepth)) {
* FileTreeWalker.Event ev = walker.walk(top);
* do {
* process(ev);
* ev = walker.next();
* } while (ev != null);
* }
* }</pre>
*
* @see Files#walkFileTree
*/
class
FileTreeWalker
{
class
FileTreeWalker
implements
Closeable
{
private
final
boolean
followLinks
;
private
final
LinkOption
[]
linkOptions
;
private
final
FileVisitor
<?
super
Path
>
visitor
;
private
final
int
maxDepth
;
private
final
ArrayDeque
<
DirectoryNode
>
stack
=
new
ArrayDeque
<>();
private
boolean
closed
;
FileTreeWalker
(
Set
<
FileVisitOption
>
options
,
FileVisitor
<?
super
Path
>
visitor
,
int
maxDepth
)
{
/**
* The element on the walking stack corresponding to a directory node.
*/
private
static
class
DirectoryNode
{
private
final
Path
dir
;
private
final
Object
key
;
private
final
DirectoryStream
<
Path
>
stream
;
private
final
Iterator
<
Path
>
iterator
;
private
boolean
skipped
;
DirectoryNode
(
Path
dir
,
Object
key
,
DirectoryStream
<
Path
>
stream
)
{
this
.
dir
=
dir
;
this
.
key
=
key
;
this
.
stream
=
stream
;
this
.
iterator
=
stream
.
iterator
();
}
Path
directory
()
{
return
dir
;
}
Object
key
()
{
return
key
;
}
DirectoryStream
<
Path
>
stream
()
{
return
stream
;
}
Iterator
<
Path
>
iterator
()
{
return
iterator
;
}
void
skip
()
{
skipped
=
true
;
}
boolean
skipped
()
{
return
skipped
;
}
}
/**
* The event types.
*/
static
enum
EventType
{
/**
* Start of a directory
*/
START_DIRECTORY
,
/**
* End of a directory
*/
END_DIRECTORY
,
/**
* An entry in a directory
*/
ENTRY
;
}
/**
* Events returned by the {@link #walk} and {@link #next} methods.
*/
static
class
Event
{
private
final
EventType
type
;
private
final
Path
file
;
private
final
BasicFileAttributes
attrs
;
private
final
IOException
ioe
;
private
Event
(
EventType
type
,
Path
file
,
BasicFileAttributes
attrs
,
IOException
ioe
)
{
this
.
type
=
type
;
this
.
file
=
file
;
this
.
attrs
=
attrs
;
this
.
ioe
=
ioe
;
}
Event
(
EventType
type
,
Path
file
,
BasicFileAttributes
attrs
)
{
this
(
type
,
file
,
attrs
,
null
);
}
Event
(
EventType
type
,
Path
file
,
IOException
ioe
)
{
this
(
type
,
file
,
null
,
ioe
);
}
EventType
type
()
{
return
type
;
}
Path
file
()
{
return
file
;
}
BasicFileAttributes
attributes
()
{
return
attrs
;
}
IOException
ioeException
()
{
return
ioe
;
}
}
/**
* Creates a {@code FileTreeWalker}.
*/
FileTreeWalker
(
Set
<
FileVisitOption
>
options
,
int
maxDepth
)
{
boolean
fl
=
false
;
for
(
FileVisitOption
option:
options
)
{
// will throw NPE if options contains null
...
...
@@ -58,191 +178,236 @@ class FileTreeWalker {
this
.
followLinks
=
fl
;
this
.
linkOptions
=
(
fl
)
?
new
LinkOption
[
0
]
:
new
LinkOption
[]
{
LinkOption
.
NOFOLLOW_LINKS
};
this
.
visitor
=
visitor
;
this
.
maxDepth
=
maxDepth
;
}
/**
* Walk file tree starting at the given file
*/
void
walk
(
Path
start
)
throws
IOException
{
FileVisitResult
result
=
walk
(
start
,
0
,
new
ArrayList
<
AncestorDirectory
>());
Objects
.
requireNonNull
(
result
,
"FileVisitor returned null"
);
}
/**
* @param file
* the directory to visit
* @param depth
* depth remaining
* @param ancestors
* use when cycle detection is enabled
* Returns the attributes of the given file, taking into account whether
* the walk is following sym links is not. The {@code canUseCached}
* argument determines whether this method can use cached attributes.
*/
private
FileVisitResult
walk
(
Path
file
,
int
depth
,
List
<
AncestorDirectory
>
ancestors
)
private
BasicFileAttributes
getAttributes
(
Path
file
,
boolean
canUseCached
)
throws
IOException
{
// if attributes are cached then use them if possible
BasicFileAttributes
attrs
=
null
;
if
((
depth
>
0
)
&&
if
(
canUseCached
&&
(
file
instanceof
BasicFileAttributesHolder
)
&&
(
System
.
getSecurityManager
()
==
null
))
{
BasicFileAttributes
cached
=
((
BasicFileAttributesHolder
)
file
).
get
();
if
(
cached
!=
null
&&
(!
followLinks
||
!
cached
.
isSymbolicLink
()))
attrs
=
cached
;
if
(
cached
!=
null
&&
(!
followLinks
||
!
cached
.
isSymbolicLink
()))
{
return
cached
;
}
}
IOException
exc
=
null
;
// attempt to get attributes of file. If fails and we are following
// links then a link target might not exist so get attributes of link
if
(
attrs
==
null
)
{
try
{
BasicFileAttributes
attrs
;
try
{
attrs
=
Files
.
readAttributes
(
file
,
BasicFileAttributes
.
class
,
linkOptions
);
}
catch
(
IOException
ioe
)
{
if
(!
followLinks
)
throw
ioe
;
// attempt to get attrmptes without following links
attrs
=
Files
.
readAttributes
(
file
,
BasicFileAttributes
.
class
,
LinkOption
.
NOFOLLOW_LINKS
);
}
return
attrs
;
}
/**
* Returns true if walking into the given directory would result in a
* file system loop/cycle.
*/
private
boolean
wouldLoop
(
Path
dir
,
Object
key
)
{
// if this directory and ancestor has a file key then we compare
// them; otherwise we use less efficient isSameFile test.
for
(
DirectoryNode
ancestor:
stack
)
{
Object
ancestorKey
=
ancestor
.
key
();
if
(
key
!=
null
&&
ancestorKey
!=
null
)
{
if
(
key
.
equals
(
ancestorKey
))
{
// cycle detected
return
true
;
}
}
else
{
try
{
attrs
=
Files
.
readAttributes
(
file
,
BasicFileAttributes
.
class
,
linkOptions
);
}
catch
(
IOException
x1
)
{
if
(
followLinks
)
{
try
{
attrs
=
Files
.
readAttributes
(
file
,
BasicFileAttributes
.
class
,
LinkOption
.
NOFOLLOW_LINKS
);
}
catch
(
IOException
x2
)
{
exc
=
x2
;
}
}
else
{
exc
=
x1
;
if
(
Files
.
isSameFile
(
dir
,
ancestor
.
directory
()))
{
// cycle detected
return
true
;
}
}
catch
(
IOException
|
SecurityException
x
)
{
// ignore
}
}
catch
(
SecurityException
x
)
{
// If access to starting file is denied then SecurityException
// is thrown, otherwise the file is ignored.
if
(
depth
==
0
)
throw
x
;
return
FileVisitResult
.
CONTINUE
;
}
}
return
false
;
}
// unable to get attributes of file
if
(
exc
!=
null
)
{
return
visitor
.
visitFileFailed
(
file
,
exc
);
/**
* Visits the given file, returning the {@code Event} corresponding to that
* visit.
*
* The {@code ignoreSecurityException} parameter determines whether
* any SecurityException should be ignored or not. If a SecurityException
* is thrown, and is ignored, then this method returns {@code null} to
* mean that there is no event corresponding to a visit to the file.
*
* The {@code canUseCached} parameter determines whether cached attributes
* for the file can be used or not.
*/
private
Event
visit
(
Path
entry
,
boolean
ignoreSecurityException
,
boolean
canUseCached
)
{
// need the file attributes
BasicFileAttributes
attrs
;
try
{
attrs
=
getAttributes
(
entry
,
canUseCached
);
}
catch
(
IOException
ioe
)
{
return
new
Event
(
EventType
.
ENTRY
,
entry
,
ioe
);
}
catch
(
SecurityException
se
)
{
if
(
ignoreSecurityException
)
return
null
;
throw
se
;
}
// at maximum depth or file is not a directory
int
depth
=
stack
.
size
();
if
(
depth
>=
maxDepth
||
!
attrs
.
isDirectory
())
{
return
visitor
.
visitFile
(
file
,
attrs
);
return
new
Event
(
EventType
.
ENTRY
,
entry
,
attrs
);
}
// check for cycles when following links
if
(
followLinks
)
{
Object
key
=
attrs
.
fileKey
();
// if this directory and ancestor has a file key then we compare
// them; otherwise we use less efficient isSameFile test.
for
(
AncestorDirectory
ancestor:
ancestors
)
{
Object
ancestorKey
=
ancestor
.
fileKey
();
if
(
key
!=
null
&&
ancestorKey
!=
null
)
{
if
(
key
.
equals
(
ancestorKey
))
{
// cycle detected
return
visitor
.
visitFileFailed
(
file
,
new
FileSystemLoopException
(
file
.
toString
()));
}
}
else
{
boolean
isSameFile
=
false
;
try
{
isSameFile
=
Files
.
isSameFile
(
file
,
ancestor
.
file
());
}
catch
(
IOException
x
)
{
// ignore
}
catch
(
SecurityException
x
)
{
// ignore
}
if
(
isSameFile
)
{
// cycle detected
return
visitor
.
visitFileFailed
(
file
,
new
FileSystemLoopException
(
file
.
toString
()));
}
}
}
ancestors
.
add
(
new
AncestorDirectory
(
file
,
key
));
if
(
followLinks
&&
wouldLoop
(
entry
,
attrs
.
fileKey
()))
{
return
new
Event
(
EventType
.
ENTRY
,
entry
,
new
FileSystemLoopException
(
entry
.
toString
()));
}
// visit directory
// file is a directory, attempt to open it
DirectoryStream
<
Path
>
stream
=
null
;
try
{
DirectoryStream
<
Path
>
stream
=
null
;
FileVisitResult
result
;
stream
=
Files
.
newDirectoryStream
(
entry
);
}
catch
(
IOException
ioe
)
{
return
new
Event
(
EventType
.
ENTRY
,
entry
,
ioe
);
}
catch
(
SecurityException
se
)
{
if
(
ignoreSecurityException
)
return
null
;
throw
se
;
}
// open the directory
try
{
stream
=
Files
.
newDirectoryStream
(
file
);
}
catch
(
IOException
x
)
{
return
visitor
.
visitFileFailed
(
file
,
x
);
}
catch
(
SecurityException
x
)
{
// ignore, as per spec
return
FileVisitResult
.
CONTINUE
;
}
// push a directory node to the stack and return an event
stack
.
push
(
new
DirectoryNode
(
entry
,
attrs
.
fileKey
(),
stream
));
return
new
Event
(
EventType
.
START_DIRECTORY
,
entry
,
attrs
);
}
// the exception notified to the postVisitDirectory method
IOException
ioe
=
null
;
// invoke preVisitDirectory and then visit each entry
try
{
result
=
visitor
.
preVisitDirectory
(
file
,
attrs
);
if
(
result
!=
FileVisitResult
.
CONTINUE
)
{
return
result
;
}
/**
* Start walking from the given file.
*/
Event
walk
(
Path
file
)
{
if
(
closed
)
throw
new
IllegalStateException
(
"Closed"
);
try
{
for
(
Path
entry:
stream
)
{
result
=
walk
(
entry
,
depth
+
1
,
ancestors
);
Event
ev
=
visit
(
file
,
false
,
// ignoreSecurityException
false
);
// canUseCached
assert
ev
!=
null
;
return
ev
;
}
// returning null will cause NPE to be thrown
if
(
result
==
null
||
result
==
FileVisitResult
.
TERMINATE
)
return
result
;
/**
* Returns the next Event or {@code null} if there are no more events or
* the walker is closed.
*/
Event
next
()
{
DirectoryNode
top
=
stack
.
peek
();
if
(
top
==
null
)
return
null
;
// stack is empty, we are done
// continue iteration of the directory at the top of the stack
Event
ev
;
do
{
Path
entry
=
null
;
IOException
ioe
=
null
;
// skip remaining siblings in this directory
if
(
result
==
FileVisitResult
.
SKIP_SIBLINGS
)
break
;
// get next entry in the directory
if
(!
top
.
skipped
())
{
Iterator
<
Path
>
iterator
=
top
.
iterator
();
try
{
if
(
iterator
.
hasNext
())
{
entry
=
iterator
.
next
();
}
}
catch
(
DirectoryIteratorException
e
)
{
// IOException will be notified to postVisitDirectory
ioe
=
e
.
getCause
();
}
catch
(
DirectoryIteratorException
x
)
{
ioe
=
x
.
getCause
();
}
}
finally
{
}
// no next entry so close and pop directory, creating corresponding event
if
(
entry
==
null
)
{
try
{
stream
.
close
();
top
.
stream
()
.
close
();
}
catch
(
IOException
e
)
{
// IOException will be notified to postVisitDirectory
if
(
ioe
==
null
)
if
(
ioe
!=
null
)
{
ioe
=
e
;
}
else
{
ioe
.
addSuppressed
(
e
);
}
}
stack
.
pop
();
return
new
Event
(
EventType
.
END_DIRECTORY
,
top
.
directory
(),
ioe
);
}
// invoke postVisitDirectory last
return
visitor
.
postVisitDirectory
(
file
,
ioe
);
// visit the entry
ev
=
visit
(
entry
,
true
,
// ignoreSecurityException
true
);
// canUseCached
}
finally
{
// remove key from trail if doing cycle detection
if
(
followLinks
)
{
ancestors
.
remove
(
ancestors
.
size
()-
1
);
}
}
}
while
(
ev
==
null
);
return
ev
;
}
private
static
class
AncestorDirectory
{
private
final
Path
dir
;
private
final
Object
key
;
AncestorDirectory
(
Path
dir
,
Object
key
)
{
this
.
dir
=
dir
;
this
.
key
=
key
;
/**
* Pops the directory node that is the current top of the stack so that
* there are no more events for the directory (including no END_DIRECTORY)
* event. This method is a no-op if the stack is empty or the walker is
* closed.
*/
void
pop
()
{
if
(!
stack
.
isEmpty
())
{
DirectoryNode
node
=
stack
.
pop
();
try
{
node
.
stream
().
close
();
}
catch
(
IOException
ignore
)
{
}
}
Path
file
()
{
return
dir
;
}
/**
* Skips the remaining entries in the directory at the top of the stack.
* This method is a no-op if the stack is empty or the walker is closed.
*/
void
skipRemainingSiblings
()
{
if
(!
stack
.
isEmpty
())
{
stack
.
peek
().
skip
();
}
Object
fileKey
()
{
return
key
;
}
/**
* Returns {@code true} if the walker is open.
*/
boolean
isOpen
()
{
return
!
closed
;
}
/**
* Closes/pops all directories on the stack.
*/
@Override
public
void
close
()
{
if
(!
closed
)
{
while
(!
stack
.
isEmpty
())
{
pop
();
}
closed
=
true
;
}
}
}
src/share/classes/java/nio/file/Files.java
浏览文件 @
5091708e
...
...
@@ -2589,7 +2589,60 @@ public final class Files {
{
if
(
maxDepth
<
0
)
throw
new
IllegalArgumentException
(
"'maxDepth' is negative"
);
new
FileTreeWalker
(
options
,
visitor
,
maxDepth
).
walk
(
start
);
/**
* Create a FileTreeWalker to walk the file tree, invoking the visitor
* for each event.
*/
try
(
FileTreeWalker
walker
=
new
FileTreeWalker
(
options
,
maxDepth
))
{
FileTreeWalker
.
Event
ev
=
walker
.
walk
(
start
);
do
{
FileVisitResult
result
;
switch
(
ev
.
type
())
{
case
ENTRY
:
IOException
ioe
=
ev
.
ioeException
();
if
(
ioe
==
null
)
{
assert
ev
.
attributes
()
!=
null
;
result
=
visitor
.
visitFile
(
ev
.
file
(),
ev
.
attributes
());
}
else
{
result
=
visitor
.
visitFileFailed
(
ev
.
file
(),
ioe
);
}
break
;
case
START_DIRECTORY
:
result
=
visitor
.
preVisitDirectory
(
ev
.
file
(),
ev
.
attributes
());
// if SKIP_SIBLINGS and SKIP_SUBTREE is returned then
// there shouldn't be any more events for the current
// directory.
if
(
result
==
FileVisitResult
.
SKIP_SUBTREE
||
result
==
FileVisitResult
.
SKIP_SIBLINGS
)
walker
.
pop
();
break
;
case
END_DIRECTORY
:
result
=
visitor
.
postVisitDirectory
(
ev
.
file
(),
ev
.
ioeException
());
// SKIP_SIBLINGS is a no-op for postVisitDirectory
if
(
result
==
FileVisitResult
.
SKIP_SIBLINGS
)
result
=
FileVisitResult
.
CONTINUE
;
break
;
default
:
throw
new
AssertionError
(
"Should not get here"
);
}
if
(
Objects
.
requireNonNull
(
result
)
!=
FileVisitResult
.
CONTINUE
)
{
if
(
result
==
FileVisitResult
.
TERMINATE
)
{
break
;
}
else
if
(
result
==
FileVisitResult
.
SKIP_SIBLINGS
)
{
walker
.
skipRemainingSiblings
();
}
}
ev
=
walker
.
next
();
}
while
(
ev
!=
null
);
}
return
start
;
}
...
...
test/java/nio/file/Files/walkFileTree/CreateFileTree.java
浏览文件 @
5091708e
...
...
@@ -32,9 +32,23 @@ import java.util.*;
public
class
CreateFileTree
{
static
final
Random
rand
=
new
Random
();
private
static
final
Random
rand
=
new
Random
();
public
static
void
main
(
String
[]
args
)
throws
IOException
{
private
static
boolean
supportsLinks
(
Path
dir
)
{
Path
link
=
dir
.
resolve
(
"testlink"
);
Path
target
=
dir
.
resolve
(
"testtarget"
);
try
{
Files
.
createSymbolicLink
(
link
,
target
);
Files
.
delete
(
link
);
return
true
;
}
catch
(
UnsupportedOperationException
x
)
{
return
false
;
}
catch
(
IOException
x
)
{
return
false
;
}
}
static
Path
create
()
throws
IOException
{
Path
top
=
Files
.
createTempDirectory
(
"tree"
);
List
<
Path
>
dirs
=
new
ArrayList
<
Path
>();
...
...
@@ -53,7 +67,6 @@ public class CreateFileTree {
dirs
.
add
(
subdir
);
}
}
assert
dirs
.
size
()
>=
2
;
// create a few regular files in the file tree
int
files
=
dirs
.
size
()
*
3
;
...
...
@@ -64,20 +77,26 @@ public class CreateFileTree {
}
// create a few sym links in the file tree so as to create cycles
int
links
=
1
+
rand
.
nextInt
(
5
);
for
(
int
i
=
0
;
i
<
links
;
i
++)
{
int
x
=
rand
.
nextInt
(
dirs
.
size
());
int
y
;
do
{
y
=
rand
.
nextInt
(
dirs
.
size
());
}
while
(
y
!=
x
);
String
name
=
"link"
+
(
i
+
1
);
Path
link
=
dirs
.
get
(
x
).
resolve
(
name
);
Path
target
=
dirs
.
get
(
y
);
Files
.
createSymbolicLink
(
link
,
target
);
if
(
supportsLinks
(
top
))
{
int
links
=
1
+
rand
.
nextInt
(
5
);
for
(
int
i
=
0
;
i
<
links
;
i
++)
{
int
x
=
rand
.
nextInt
(
dirs
.
size
());
int
y
;
do
{
y
=
rand
.
nextInt
(
dirs
.
size
());
}
while
(
y
!=
x
);
String
name
=
"link"
+
(
i
+
1
);
Path
link
=
dirs
.
get
(
x
).
resolve
(
name
);
Path
target
=
dirs
.
get
(
y
);
Files
.
createSymbolicLink
(
link
,
target
);
}
}
// done
return
top
;
}
public
static
void
main
(
String
[]
args
)
throws
IOException
{
Path
top
=
create
();
System
.
out
.
println
(
top
);
}
}
test/java/nio/file/Files/walkFileTree/MaxDepth.java
浏览文件 @
5091708e
...
...
@@ -21,18 +21,21 @@
* questions.
*/
/*
* @test
* @summary Unit test for Files.walkFileTree to test maxDepth parameter
* @compile MaxDepth.java CreateFileTree.java
* @run main MaxDepth
*/
import
java.nio.file.*
;
import
java.nio.file.attribute.*
;
import
java.io.IOException
;
import
java.util.*
;
/**
* Unit test for Files.walkFileTree to test maxDepth parameter
*/
public
class
MaxDepth
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
final
Path
top
=
Paths
.
get
(
args
[
0
]
);
final
Path
top
=
CreateFileTree
.
create
(
);
for
(
int
i
=
0
;
i
<
5
;
i
++)
{
Set
<
FileVisitOption
>
opts
=
Collections
.
emptySet
();
...
...
test/java/nio/file/Files/walkFileTree/SkipSiblings.java
浏览文件 @
5091708e
...
...
@@ -21,15 +21,18 @@
* questions.
*/
/*
* @test
* @summary Unit test for Files.walkFileTree to test SKIP_SIBLINGS return value
* @compile SkipSiblings.java CreateFileTree.java
* @run main SkipSiblings
*/
import
java.nio.file.*
;
import
java.nio.file.attribute.*
;
import
java.io.IOException
;
import
java.util.*
;
/**
* Unit test for Files.walkFileTree to test SKIP_SIBLINGS return value.
*/
public
class
SkipSiblings
{
static
final
Random
rand
=
new
Random
();
...
...
@@ -52,7 +55,7 @@ public class SkipSiblings {
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
Path
dir
=
Paths
.
get
(
args
[
0
]
);
Path
dir
=
CreateFileTree
.
create
(
);
Files
.
walkFileTree
(
dir
,
new
SimpleFileVisitor
<
Path
>()
{
@Override
...
...
@@ -74,7 +77,11 @@ public class SkipSiblings {
if
(
x
!=
null
)
throw
new
RuntimeException
(
x
);
check
(
dir
);
return
FileVisitResult
.
CONTINUE
;
if
(
rand
.
nextBoolean
())
{
return
FileVisitResult
.
CONTINUE
;
}
else
{
return
FileVisitResult
.
SKIP_SIBLINGS
;
}
}
});
}
...
...
test/java/nio/file/Files/walkFileTree/SkipSubtree.java
0 → 100644
浏览文件 @
5091708e
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @summary Unit test for Files.walkFileTree to test SKIP_SUBTREE return value
* @compile SkipSubtree.java CreateFileTree.java
* @run main SkipSubtree
*/
import
java.nio.file.*
;
import
java.nio.file.attribute.BasicFileAttributes
;
import
java.io.IOException
;
import
java.util.HashSet
;
import
java.util.Random
;
import
java.util.Set
;
public
class
SkipSubtree
{
static
final
Random
rand
=
new
Random
();
static
final
Set
<
Path
>
skipped
=
new
HashSet
<>();
// check if this path should have been skipped
static
void
check
(
Path
path
)
{
do
{
if
(
skipped
.
contains
(
path
))
throw
new
RuntimeException
(
path
+
" should not have been visited"
);
path
=
path
.
getParent
();
}
while
(
path
!=
null
);
}
// indicates if the subtree should be skipped
static
boolean
skip
(
Path
path
)
{
if
(
rand
.
nextInt
(
3
)
==
0
)
{
skipped
.
add
(
path
);
return
true
;
}
return
false
;
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
Path
dir
=
CreateFileTree
.
create
();
Files
.
walkFileTree
(
dir
,
new
SimpleFileVisitor
<
Path
>()
{
@Override
public
FileVisitResult
preVisitDirectory
(
Path
dir
,
BasicFileAttributes
attrs
)
{
check
(
dir
);
if
(
skip
(
dir
))
return
FileVisitResult
.
SKIP_SUBTREE
;
return
FileVisitResult
.
CONTINUE
;
}
@Override
public
FileVisitResult
visitFile
(
Path
file
,
BasicFileAttributes
attrs
)
{
check
(
file
);
return
FileVisitResult
.
CONTINUE
;
}
@Override
public
FileVisitResult
postVisitDirectory
(
Path
dir
,
IOException
x
)
{
if
(
x
!=
null
)
throw
new
RuntimeException
(
x
);
check
(
dir
);
return
FileVisitResult
.
CONTINUE
;
}
});
}
}
test/java/nio/file/Files/walkFileTree/TerminateWalk.java
浏览文件 @
5091708e
...
...
@@ -21,15 +21,18 @@
* questions.
*/
/*
* @test
* @summary Unit test for Files.walkFileTree to test TERMINATE return value
* @compile TerminateWalk.java CreateFileTree.java
* @run main TerminateWalk
*/
import
java.nio.file.*
;
import
java.nio.file.attribute.*
;
import
java.io.IOException
;
import
java.util.*
;
/**
* Unit test for Files.walkFileTree to test TERMINATE return value
*/
public
class
TerminateWalk
{
static
final
Random
rand
=
new
Random
();
...
...
@@ -47,7 +50,7 @@ public class TerminateWalk {
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
Path
dir
=
Paths
.
get
(
args
[
0
]
);
Path
dir
=
CreateFileTree
.
create
(
);
Files
.
walkFileTree
(
dir
,
new
SimpleFileVisitor
<
Path
>()
{
@Override
...
...
test/java/nio/file/Files/walkFileTree/
walk_file_tree
.sh
→
test/java/nio/file/Files/walkFileTree/
find
.sh
浏览文件 @
5091708e
...
...
@@ -23,9 +23,9 @@
# @test
# @bug 4313887 6907737
# @summary
Unit test for walkFileTree method
# @build CreateFileTree PrintFileTree
SkipSiblings TerminateWalk MaxDepth
# @run shell
walk_file_tree
.sh
# @summary
Tests that walkFileTree is consistent with the native find program
# @build CreateFileTree PrintFileTree
# @run shell
find
.sh
# if TESTJAVA isn't set then we assume an interactive run.
...
...
@@ -76,18 +76,6 @@ if [ $? != 0 ];
if
[
$?
!=
0
]
;
then
failures
=
`
expr
$failures
+ 1
`
;
fi
fi
# test SKIP_SIBLINGS
$JAVA
${
TESTVMOPTS
}
SkipSiblings
"
$ROOT
"
if
[
$?
!=
0
]
;
then
failures
=
`
expr
$failures
+ 1
`
;
fi
# test TERMINATE
$JAVA
${
TESTVMOPTS
}
TerminateWalk
"
$ROOT
"
if
[
$?
!=
0
]
;
then
failures
=
`
expr
$failures
+ 1
`
;
fi
# test maxDepth
$JAVA
${
TESTVMOPTS
}
MaxDepth
"
$ROOT
"
if
[
$?
!=
0
]
;
then
failures
=
`
expr
$failures
+ 1
`
;
fi
# clean-up
rm
-r
"
$ROOT
"
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录