How to read a text file from resources in Kotlin?

Kotlin

Kotlin Problem Overview


I want to write a Spek test in Kotlin. The test should read an HTML file from the src/test/resources folder. How to do it?

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

Kotlin Solutions


Solution 1 - Kotlin

val fileContent = MySpec::class.java.getResource("/html/file.html").readText()

Solution 2 - Kotlin

No idea why this is so hard, but the simplest way I've found (without having to refer to a particular class) is:

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

It returns null if no resource with this name is found (as documented).

And then passing in an absolute URL, e.g.

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

Solution 3 - Kotlin

another slightly different solution:

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

Solution 4 - Kotlin

A slightly different solution:

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

            var fileContent = ""

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

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

Solution 5 - Kotlin

Kotlin + Spring way:

@Autowired
private lateinit var resourceLoader: ResourceLoader

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

Solution 6 - Kotlin

Using Google Guava library Resources class:

import com.google.common.io.Resources;

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

Solution 7 - Kotlin

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

Solution 8 - Kotlin

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

Solution 9 - Kotlin

This is the way that I prefer to do it:

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

Solution 10 - Kotlin

this top-level kotlin function will do the job in any case

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

or if you want a more robust function

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

Solution 11 - Kotlin

FYI: In all the above cases. getResource() is unsafe way of using nullable.

Haven't tried locally but I prefer this way:

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

Or even as custom datatype function

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

and then you can call directly on path like:

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

Solution 12 - Kotlin

You might find the File class useful:

import java.io.File

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionOlafView Question on Stackoverflow
Solution 1 - KotlinJB NizetView Answer on Stackoverflow
Solution 2 - KotlinRussell BriggsView Answer on Stackoverflow
Solution 3 - KotlinjhodgesView Answer on Stackoverflow
Solution 4 - KotlinOlafView Answer on Stackoverflow
Solution 5 - KotlinnaXa stands with UkraineView Answer on Stackoverflow
Solution 6 - KotlinLu55View Answer on Stackoverflow
Solution 7 - KotlinOlafView Answer on Stackoverflow
Solution 8 - KotlinjivimbergView Answer on Stackoverflow
Solution 9 - KotlinsaidaspenView Answer on Stackoverflow
Solution 10 - KotlinsaulpalvView Answer on Stackoverflow
Solution 11 - Kotlinbh4r4thView Answer on Stackoverflow
Solution 12 - KotlinKrzysztof ZiomekView Answer on Stackoverflow