https://kotlinlang.org logo
#getting-started
Title
# getting-started
t

tomas-mrkvička

11/27/2023, 11:47 AM
Hi there. I want to find a file by its name within a given directory (and possible subdirectories). I found that
FileWalkDirection.BOTTOM_UP
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/-file-walk-direction/ should do the thing because I want to check files first and then go deep. But
BOTTOM_UP
goes to directory first regardless its documentation:
Depth-first search, directory is visited AFTER its files
. What am I missing here? Thank you.
e

ephemient

11/27/2023, 11:53 AM
do you have a reproducible example?
File.walk
works as expected for me,
Copy code
File(".").walk(FileWalkDirection.TOP_DOWN).first() == File(".")
File(".").walk(FileWalkDirection.BOTTOM_UP).last() == File(".")
t

tomas-mrkvička

11/27/2023, 12:58 PM
I have just tried some examples and it looks like that
filter
is the one to blame.
File("/C:*/foo*").walkBottomUp().filter { file -> file.name == "gradle.properties" }.forEach { file -> println(file.absolutePath) }
prints:
Copy code
C:\foo\xxx\gradle.properties
C:\foo\gradle.properties
C:\foo\asd\gradle.properties
C:\foo\zzz\gradle.properties
C:\foo\yyy\gradle.properties
So it looks like that filtering does something fishy with ordering. In our real code we use
.firstOrNull()
after
filter {}
. So
forEach {}
in my example is used to just print occurrences.
e

ephemient

11/27/2023, 1:07 PM
what's wrong with that order? there's no guarantee on relative ordering between children at the same level, such as
C:\foo\gradle.properties
and
C:\foo\xxx
t

tomas-mrkvička

11/27/2023, 1:11 PM
I am expecting that if
C:\foo\gradle.properties
is a file, it should go to the
filter
method before
C:\foo\xxx\gradle.properties
(because
BOTTOM_UP
observers files first) and therefore should be first in the terminal operation.
File("/C:/foo").walkBottomUp().find { file -> file.name == "gradle.properties" }?.absolutePath)
also prints
C:\foo\xxx\gradle.properties
as a winner even though there is a
C:\foo\gradle.properties
in the root of
C:/foo
directory. Am I missing any fundamental Kotlin knowledge here?
e

ephemient

11/27/2023, 3:16 PM
it only means that a file's parent directory is visited before or after the file, not all directories before or after all files
think of a tree traversal:
Copy code
A
 /|\
B C D
|
E
in preorder (top-down), A is visited before BCD, but BCD have no order among themselves, and thus E may be visited either before or after CD (but always after B). in postorder (bottom-up), E is visited before B, and BCD is visited before A, but similarly there is no order among BCD so E may be visited before or after CD.
t

tomas-mrkvička

11/27/2023, 4:08 PM
Ouch. Now I make sense to me. Thank you very much for the explanation!!