IllegalStateException occurs when using `partition` on `File.glob` result
The following code:
val dir: File = cwd / "data/inegi/ensaios_rolamentos_3"
val matchNames = "*.csv"
val matches_tmp: Iterator[File] = dir.glob(matchNames)
val (good, bad) = matches_tmp.partition{ e => e.path.getFileName.toString.contains("norm") }
println(s"good.size = ${good.size}")
println(s"bad.size = ${bad.size}")
Picks up 90 files. It should split the list into two 45 element lists. However this results in the following exception on the first size call.
java.lang.IllegalStateException:
[info] at java.nio.file.FileTreeIterator.hasNext(FileTreeIterator.java:103)
[info] at java.util.Spliterators$IteratorSpliterator.tryAdvance(Spliterators.java:1811)
[info] at java.util.stream.StreamSpliterators$WrappingSpliterator.lambda$initPartialTraversalState$0(StreamSpliterators.java:294)
[info] at java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.fillBuffer(StreamSpliterators.java:206)
[info] at java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.doAdvance(StreamSpliterators.java:169)
[info] at java.util.stream.StreamSpliterators$WrappingSpliterator.tryAdvance(StreamSpliterators.java:300)
[info] at java.util.Spliterators$1Adapter.hasNext(Spliterators.java:681)
[info] at scala.collection.convert.Wrappers$JIteratorWrapper.hasNext(Wrappers.scala:39)
[info] at better.files.Dispose$FlatMap$Implicits$traversableFlatMap$.$anonfun$apply$3(Dispose.scala:160)
[info] at better.files.Implicits$IteratorExtensions$$anon$2.hasNext(Implicits.scala:60)
One can circumvent the issue by converting the iterator so:
val (good, bad) = matches_tmp.toList.partition{ e => e.path.getFileName.toString.contains("norm") }
Using Scala 2.12.6 and the latest version of better-files.
Hello, Thank you for the report!
This could be reproduced and reduced to simple directory walk (and ultimately to the java.nio.file.Files.Walk):
// result would be java.lang.IllegalStateException:
// val result: Iterator[File] = dir.listRecursively()
// this will work
val result: Iterator[File] = dir.listRecursively().toSeq.toIterator
val (good, bad) = result.partition{ e => e.path.getFileName.toString.contains("a") }
println(s"good.size = ${good.size}")
println(s"bad.size = ${bad.size}")
toSeq.toIterator would "fix" this with API compatible way in walk of better-files. But then there would be invisible toSeq, which is not nice. I don't know offhand how to fix this at Java level.
Reopenning this since this is almost impossible to fix. Since these iterators are "autoclosing" (i.e. they close underlying resource). So when we "partition them" we are sharing a resource between 2 iterators and when first one finishes it closes that resource making the 2nd one throw this exception