Skip to content

Commit 9c8e6a2

Browse files
Fix Files.walk behavior
Java's Files.walk() ends up in an infinite loop when iterating over files on GCS because the iterator returns the directory itself as the first result, so Files.walk() tries to cd there and we're stuck. The fix is to check for that path and not return it.
1 parent 0c89651 commit 9c8e6a2

1 file changed

Lines changed: 10 additions & 3 deletions

File tree

google-cloud-contrib/google-cloud-nio/src/main/java/com/google/cloud/storage/contrib/nio/CloudStorageFileSystemProvider.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,12 @@ private static class LazyPathIterator extends AbstractIterator<Path> {
9797
private final Iterator<Blob> blobIterator;
9898
private final Filter<? super Path> filter;
9999
private final CloudStorageFileSystem fileSystem;
100+
private final String prefix;
100101

101-
LazyPathIterator(CloudStorageFileSystem fileSystem, Iterator<Blob> blobIterator,
102+
LazyPathIterator(CloudStorageFileSystem fileSystem, String prefix,
103+
Iterator<Blob> blobIterator,
102104
Filter<? super Path> filter) {
105+
this.prefix = prefix;
103106
this.blobIterator = blobIterator;
104107
this.filter = filter;
105108
this.fileSystem = fileSystem;
@@ -110,6 +113,10 @@ protected Path computeNext() {
110113
while (blobIterator.hasNext()) {
111114
Path path = fileSystem.getPath(blobIterator.next().getName());
112115
try {
116+
if (path.toString().equals(prefix)) {
117+
// do not return ourselves, because that confuses recursive descents.
118+
continue;
119+
}
113120
if (filter.accept(path)) {
114121
return path;
115122
}
@@ -617,14 +624,14 @@ public DirectoryStream<Path> newDirectoryStream(Path dir, final Filter<? super P
617624
final CloudStoragePath cloudPath = CloudStorageUtil.checkPath(dir);
618625
checkNotNull(filter);
619626
initStorage();
620-
String prefix = cloudPath.toRealPath().toString();
627+
final String prefix = cloudPath.toRealPath().toString();
621628
final Iterator<Blob> blobIterator = storage.list(cloudPath.bucket(),
622629
Storage.BlobListOption.prefix(prefix), Storage.BlobListOption.currentDirectory(),
623630
Storage.BlobListOption.fields()).iterateAll().iterator();
624631
return new DirectoryStream<Path>() {
625632
@Override
626633
public Iterator<Path> iterator() {
627-
return new LazyPathIterator(cloudPath.getFileSystem(), blobIterator, filter);
634+
return new LazyPathIterator(cloudPath.getFileSystem(), prefix, blobIterator, filter);
628635
}
629636

630637
@Override

0 commit comments

Comments
 (0)