Files.walkFileTree() visits a file leading to a loop with LOOP_DETECT option enabled

Alan Bateman Alan.Bateman at Sun.COM
Thu Aug 7 01:42:07 PDT 2008


Rajendra Gutupalli wrote:
> Hi Alan,
>
> I have a entry in directory structure that references ancestor of the 
> directory (this is a loop according to spec) but still it is being 
> visited by Files.walkFileTree().
> I created a directory structure as follows.  /java/DirA/dirClink is a 
> link file which points to /java/DirB/DirC and /java/DirB/DirC/dirBlink 
> points to /java/DirB.
> Actually if there is link which points to ancestor that is not being 
> visited by Files.walkFileTree(). Here is the scenario where it visits.
>
> Directory Structure:
> /java
>     DirA
>            dirClink -> /java/DirB/DirC
>     DirB
>            DirC
>                   dirBlink -> /java/DirB/  (This is the link which 
> should not be visited at all)
>
> When I run code with all FileVisitOptions, I got the following print
>
> bash-3.00$ ./jdk1.7.0/bin/java TreeTest03 /java/DirA
> pre dir /java/DirA
> pre dir /java/DirA/dirClink
> pre dir /java/DirA/dirClink/dirBlink post dir 
> /java/DirA/dirClink/dirBlink
> post dir /java/DirA/dirClink
> post dir /java/DirA
>
> So my query here is-  Should pre and post VisitDirectory() be opened 
> for the loop file /java/DirA/dirClink/dirBlink?
>
> >> when I run the code with /java/DirB input , then  the pre and post 
> VisitDirectory() methods will not be called for the loop file 
> /java/DirB/dirBlink
>
> bash-3.00$ ./jdk1.7.0/bin/java TreeTest03 /java/DirB
> pre dir /java/DirB
> pre dir /java/DirB/DirC
> post dir /java/DirB/DirC
> post dir /java/DirB
The cycles in this directory structure do indeed highlight a problem. 
The cycles are correctly detected but the "skipped" directories aren't 
notified to the FileVisitor (this is a bug in the Files.walkFileTree's 
spec). In a recursive copy for example, which follows sym links by 
default, then the notification can be minimally used to report a warning 
(like what "cp -r" would do for such cases). Here's what you should get 
for this:

 (pre) java
 (pre) java/DirA
 (pre) java/DirA/dirClink
 (pre) java/DirA/dirClink/dirBlink
(skip) java/DirA/dirClink/dirBlink/DirC
(post) java/DirA/dirClink/dirBlink
(post) java/DirA/dirClink
(post) java/DirA
 (pre) java/DirB
 (pre) java/DirB/DirC
(skip) java/DirB/DirC/dirBlink
(post) java/DirB/DirC
(post) java/DirB
(post) java

The lines with "(skip)" are where a cycle is detected and aren't 
(currently) notified to you.

-Alan.






More information about the nio-dev mailing list