Reputation: 1134
Is there a way to get list of all files in "resources" folder in Kotlin?
I can read specific file as
Application::class.java.getResourceAsStream("/folder/filename.ext")
But sometimes I just want to extract everything from folder "folder" to an external directory.
Upvotes: 14
Views: 32353
Reputation: 11
Maybe you can try like the one below
fun getAllFiles(name: String) {
val files = Base64Util::class.java.classLoader.getResources(name)
val directoryPath = files.asIterator().next().path
print("directoryPath - $directoryPath")
val directory = File(directoryPath)
if (directory.isDirectory) {
directory.listFiles()?.forEach {
println("File - ${it.absolutePath}")
}
}
}
Upvotes: 0
Reputation: 9106
The task has two distinct parts:
For 1 you can use Java's getResource
:
val dir = File( object {}.javaClass.getResource(directoryPath).file )
For 2 you can use Kotlin's File.walk extension function that returns a sequence of files you can process, e.g:
dir.walk().forEach { f ->
if(f.isFile) {
println("file ${f.name}")
} else {
println("dir ${f.name}")
}
}
Put together you may end up with the following code:
fun onEachResource(path: String, action: (File) -> Unit) {
fun resource2file(path: String): File {
val resourceURL = object {}.javaClass.getResource(path)
return File(checkNotNull(resourceURL, { "Path not found: '$path'" }).file)
}
with(resource2file(path)) {
this.walk().forEach { f -> action(f) }
}
}
so that if you have resources/nested
direcory, you can:
fun main() {
val print = { f: File ->
when (f.isFile) {
true -> println("[F] ${f.absolutePath}")
false -> println("[D] ${f.absolutePath}")
}
}
onEachResource("/nested", print)
}
Upvotes: 8
Reputation: 26210
Here is a solution to iterate over JAR-packed resources on JVM:
fun iterateResources(resourceDir: String) {
val resource = MethodHandles.lookup().lookupClass().classLoader.getResource(resourceDir)
?: error("Resource $resourceDir was not found")
FileSystems.newFileSystem(resource.toURI(), emptyMap<String, String>()).use { fs ->
Files.walk(fs.getPath(resourceDir))
.filter { it.extension == "ttf" }
.forEach { file -> println(file.toUri().toString()) }
}
}
Upvotes: 2
Reputation: 753
As I struggled with the same issue and couldn't find a concrete answer, so I had to write one myself.
Here is my solution:
fun getAllFilesInResources()
{
val projectDirAbsolutePath = Paths.get("").toAbsolutePath().toString()
val resourcesPath = Paths.get(projectDirAbsolutePath, "/src/main/resources")
val paths = Files.walk(resourcesPath)
.filter { item -> Files.isRegularFile(item) }
.filter { item -> item.toString().endsWith(".txt") }
.forEach { item -> println("filename: $item") }
}
Here I have parsed through all the files in the /src/main/resources folder and then filtered only the regular files (no directories included) and then filtered for the text files within the resources directory.
The output is a list of all the absolute file paths with the extension .txt in the resources folder. Now you can use these paths to copy the files to an external folder.
Upvotes: 15
Reputation: 28288
There are no methods for it (i.e. Application::class.java.listFilesInDirectory("/folder/")
), but you can create your own system to list the files in a directory:
@Throws(IOException::class)
fun getResourceFiles(path: String): List<String> = getResourceAsStream(path).use{
return if(it == null) emptyList()
else BufferedReader(InputStreamReader(it)).readLines()
}
private fun getResourceAsStream(resource: String): InputStream? =
Thread.currentThread().contextClassLoader.getResourceAsStream(resource)
?: resource::class.java.getResourceAsStream(resource)
Then just call getResourceFiles("/folder/")
and you'll get a list of files in the folder, assuming it's in the classpath.
This works because Kotlin has an extension function that reads lines into a List of Strings. The declaration is:
/**
* Reads this reader content as a list of lines.
*
* Do not use this function for huge files.
*/
public fun Reader.readLines(): List<String> {
val result = arrayListOf<String>()
forEachLine { result.add(it) }
return result
}
Upvotes: 5