如何从 Kotlin 的资源中读取文本文件?

我想在 Kotlin 写一个 Spek 测试。测试应该从 src/test/resources文件夹读取 HTML 文件。怎么做?

class MySpec : Spek({


describe("blah blah") {


given("blah blah") {


var fileContent : String = ""


beforeEachTest {
// How to read the file file.html in src/test/resources/html
fileContent = ...
}


it("should blah blah") {
...
}
}
}
})
145675 次浏览
val fileContent = MySpec::class.java.getResource("/html/file.html").readText()

一个略有不同的解决方案:

class MySpec : Spek({
describe("blah blah") {
given("blah blah") {


var fileContent = ""


beforeEachTest {
html = this.javaClass.getResource("/html/file.html").readText()
}


it("should blah blah") {
...
}
}
}
})

另一个略有不同的解决方案:

@Test
fun basicTest() {
"/html/file.html".asResource {
// test on `it` here...
println(it)
}


}


fun String.asResource(work: (String) -> Unit) {
val content = this.javaClass::class.java.getResource(this).readText()
work(content)
}

不知道为什么这么难,但我找到的最简单的方法(不需要引用特定的类)是:

fun getResourceAsText(path: String): String? =
object {}.javaClass.getResource(path)?.readText()

如果没有找到具有此名称的资源(记录在案) ,则返回 null

然后传入一个绝对 URL,例如。

val html = getResourceAsText("/www/index.html")!!
val fileContent = javaClass.getResource("/html/file.html").readText()

科特林 + 春天之路:

@Autowired
private lateinit var resourceLoader: ResourceLoader


fun load() {
val html = resourceLoader.getResource("classpath:html/file.html").file
.readText(charset = Charsets.UTF_8)
}

你可能会发现 File 类很有用:

import java.io.File


fun main(args: Array<String>) {
val content = File("src/main/resources/input.txt").readText()
print(content)
}

使用谷歌番石榴库 资源课:

import com.google.common.io.Resources;


val fileContent: String = Resources.getResource("/html/file.html").readText()
private fun loadResource(file: String) = {}::class.java.getResource(file).readText()

我更喜欢这样做:

fun getResourceText(path: String): String {
return File(ClassLoader.getSystemResource(path).file).readText()
}

这个顶级的 kotlin 函数在任何情况下都可以完成任务

fun loadResource(path: String): URL {
return Thread.currentThread().contextClassLoader.getResource(path)
}

或者你想要一个更健壮的函数

fun loadResource(path: String): URL {
val resource = Thread.currentThread().contextClassLoader.getResource(path)
requireNotNull(resource) { "Resource $path not found" }
return resource
}

提示: 在以上所有情况下,getResource()是使用可空的不安全的方式。

没有在本地尝试过,但我更喜欢这种方式:

fun readFile(resourcePath: String) = String::class.java.getResource(resourcePath)?.readText() ?: "<handle default. or handle custom exception>"

甚至可以作为自定义数据类型函数

private fun String.asResource() = this::class.java.getResource(resourcePath)?.readText() ?: "<handle default. or handle custom exception>"

然后你可以直接在路径上调用,比如:

// For suppose
val path = "/src/test/resources"
val content = path.asResource()

我更喜欢这样阅读资源:

object {}.javaClass.getResourceAsStream("/html/file.html")?.use { it.reader(Charsets.UTF_8).readText() }

说明:

  • 类路径上的资源基本上可以在任何地方,例如打包在另一个. jar 文件中。
    在这些情况下,通过从 getResource方法返回的 URL 类访问资源将失败。但是通过方法 getResourceAsStream访问在任何情况下都可以工作。
  • object {} -这不是很好的语法,但是它不依赖于类 MyClass的名称,甚至在静态(补偿对象)块中也可以工作。
  • use 关闭流-在大多数情况下,这是不必要的,但可能有一些特殊的类加载器,这可能需要它。
  • reader(Charsets.UTF_8) -UTF _ 8是默认编码,但我更喜欢显式的编码。如果你将你的资源文件编码在其他编码,例如 ISO-8859-2,你不会忽视它。