The java.nio.file.Files class has a walk method that returns a Stream used to walk a file tree. The example program lists out the 5 largest files given a starting path and demonstrates how to easily walk through a file system in Kotlin.
package ch9.files import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths import java.util.stream.Collectors.toList private fun Path.size() : Long { return try { Files.size(this) } catch (e : Exception){ -1 } } fun main(args: Array<String>){ if(args.isNotEmpty()){ val path = Paths.get(args[0]) //Open a Stream object Files.walk(path) //Sort by size .sorted { lhs : Path?, rhs : Path? -> compareValues(lhs?.size() ?: -1, rhs?.size() ?: -1)} //Collect the result into a list .collect(toList()) //Now reverse the list so that the largest file is first .reversed() .stream() //Open another stream and collect up to 5 files .limit(5) //Now print the results .forEach({it -> println("${it.fileName} \t ${it.size()}") }) } else { println("Usage: start path") } }
Detailed Explanation
The program parses the command line arguments and returns a Path object (line 18). The Path object is passed to the Files.walk() method on line 21. The walk() method returns a Stream object that opens up all of the operations found on a Java 8 Stream. In our case, we wish to sort all files by their size (using the Path.size() extension function found on lines 8-14) on line 23. The result is collected into a list on line 25.
By default, our files are sorted smallest to largest. We can either rework the comparator used on line 23 to reverse sort or just call the reversed() method on the list object. The former idea is most likely more performant but later is very readable. Finally, since we are interested in the five largest files, we open another Stream on the list and limit it to 5 elements. The final operation is to call forEach on the list and print the file name and its size.
References
https://docs.oracle.com/javase/8/docs/api/?java/io/File.html