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

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

我想用 Kotlin 写一个 Spek 测试。
如何从

src/test/resources
文件夹中读取 HTML 文件?

class MySpec : Spek(
    {
        describe("blah blah") {
            given("blah blah") {
                var fileContent: String = ""
                beforeEachTest {
                    // How to read the file.html in src/test/resources/html/
                    fileContent = ...
                }
                it("should blah blah") {
                    ...
                }
            }
        }
    }
)
kotlin file-io classpath classloader
15个回答
193
投票
val fileContent = MySpec::class.java.getResource("/html/file.html").readText()

74
投票

不知道为什么这这么难,但我发现的最简单的方法(无需参考特定类)是:

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

如果没有找到具有此名称的资源(

如文档
),它返回null

然后传入绝对URL,例如

val html = getResourceAsText("/www/index.html")!!

32
投票

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

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

19
投票

略有不同的解决方案:

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

            var fileContent = ""

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

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

14
投票

Kotlin + 弹簧方式:

@Autowired
private lateinit var resourceLoader: ResourceLoader

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

11
投票

使用谷歌Guava库资源类

import com.google.common.io.Resources;

val fileContent: String = Resources.getResource("/html/file.html").readText()

8
投票
private fun loadResource(file: String) = {}::class.java.getResource(file).readText()

7
投票
val fileContent = javaClass.getResource("/html/file.html").readText()

7
投票

这是我喜欢的方式:

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

3
投票

这个顶级 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
}

1
投票

仅供参考:在上述所有情况下。

getResource()
是使用 nullable 的不安全方式。

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

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

0
投票

我更喜欢这样的阅读资源:

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

解释:

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

0
投票

另一种处理空资源的变体:

val content = object {}.javaClass
    .getResource("/html/file.html")
    ?.let(URL::readText)
    ?: error("Cannot open/find the file")
//  ?: "default text" // Instead of error()

0
投票
fun Any.resourceString(path: String): String =
    this.javaClass.getResource(path)?.readText() ?: error("Can't load resource at $path")

对该扩展函数的调用看起来相对于进行调用的类。


-4
投票

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

import java.io.File

fun main(args: Array<String>) {
  val content = File("src/main/resources/input.txt").readText()
  print(content)
} 
© www.soinside.com 2019 - 2024. All rights reserved.