Kotlin:获取资源文件夹中所有文件的列表

问题描述 投票:0回答:4

有没有办法获取 Kotlin 中“资源”文件夹中所有文件的列表?

我可以将特定文件读取为

Application::class.java.getResourceAsStream("/folder/filename.ext")

但有时我只想将文件夹“folder”中的所有内容提取到外部目录。

kotlin resources classpath
4个回答
15
投票

由于我遇到了同样的问题并且找不到具体的答案,所以我不得不自己写一个。

这是我的解决方案:

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") }
}

这里我解析了 /src/main/resources 文件夹中的所有文件,然后仅过滤常规文件(不包括目录),然后过滤 resources 目录中的文本文件。

输出是资源文件夹中扩展名为 .txt 的所有绝对文件路径的列表。现在您可以使用这些路径将文件复制到外部文件夹。


7
投票

该任务有两个不同的部分:

  1. 获取代表资源目录的文件
  2. 遍历目录

对于1,您可以使用Java的

getResource

val dir = File( object {}.javaClass.getResource(directoryPath).file )

对于 2,您可以使用 Kotlin 的 File.walk 扩展函数,该函数返回您可以处理的文件的 序列,例如:

dir.walk().forEach { f ->
    if(f.isFile) {
        println("file ${f.name}")
    } else {
        println("dir ${f.name}")
    }
}

放在一起你可能会得到以下代码:

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) }
    }
}

这样,如果您有

resources/nested
direcory,您可以:

fun main() {
    
    val print = { f: File ->
        when (f.isFile) {
            true -> println("[F] ${f.absolutePath}")
            false -> println("[D] ${f.absolutePath}")
        }
    }
    
    onEachResource("/nested", print)
}

5
投票

没有任何方法(即

Application::class.java.listFilesInDirectory("/folder/")
),但您可以创建自己的系统来列出目录中的文件:

@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)

然后只需调用

getResourceFiles("/folder/")
,您将获得文件夹中的文件列表,假设它位于类路径中。

这是可行的,因为 Kotlin 有一个扩展函数,可以将行读入字符串列表。声明是:

/**
 * 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
}

1
投票

这是在 JVM 上迭代JAR 打包资源的解决方案:

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()) }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.