Kotlin의 리소스에서 텍스트 파일을 읽는 방법은 무엇입니까?


97

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

답변:


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

30
나를 위해이 작동하지 않았다, 나는로 변경했다this::class.java.classLoader.getResource("/html/file.html").readText()
pavlos163

4
나에게이 두 가지 옵션은 모두 Android 앱에서 작동했습니다 ( /하나의 추가 옵션 은 다른 하나에서는 제거되어야 함). this::class.java.getResource("/html/file.html").readText()그리고this::class.java.classLoader.getResource("html/file.html").‌​readText()
Franco

20
val fileContent = javaClass.getResource("/html/file.html").readText()작업도 짧은 않습니다
프랭크 Neblung

1
이상하게도 나는 항상 선행 슬래시가 필요합니다. 예를 들어 파일이 리소스 루트 디렉토리에있는 경우에도 "/file.html"로 참조해야합니다.
Somaiah Kumbera

28

또 다른 약간 다른 솔루션 :

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

확장 기능의 좋은 사용! 그런데 왜 여기서 람다 함수를 사용합니까? 그것은 나에게별로 의미가 없습니다. 게다가 그 this부분은 나를 위해 작동하지 않았습니다. 따라서 다음을 추천합니다.fun String.asResource(): URL? = object {}.javaClass.getResource(this)
Qw3ry

파일을 선언 한 다음 해당 파일의 내용을 작업하는이 방법이 마음에 듭니다. 개인적 선호도 같아요. this위의 예에서 문자열 개체를 참조합니다.
jhodges 19

확장 기능의 끔찍한 남용입니다. 파일로드는 String 클래스의 문제가 아닙니다.
Ben

이 맥락에 있습니다. 나는 이것을 전 세계적으로 사용하거나 테스트 클래스 외부에서 사용하지 않을 것입니다. 여기서는 매핑 기능에 더 가깝다고 생각합니다.
jhodges

28

이것이 왜 그렇게 어려운지 모르겠지만 내가 찾은 가장 간단한 방법은 (특정 클래스를 참조하지 않고도) 다음과 같습니다.

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

그런 다음 절대 URL을 전달합니다. 예 :

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

되어 {}필요? 왜 안돼 javaClass.getResource(path).readText()?
andrewgazelka

2
javaClass는 docs kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/java-class.html 에 따라 객체에서 호출되어야합니다. 만약 그것이없이 작동한다면 당신의 삶을 위해 가십시오 :)
Russell Briggs

3
위의 방법의 한 가지 단점은 모든 리소스 액세스에 대해 새 개체를 생성한다는 것입니다. 함수 외부에 더미 객체를 저장하는 것이 좋습니다.
Russell Briggs

@RussellBriggs tbh 나는 그다지 중요하지 않다고 생각합니다. 디스크 액세스를 수행하는 경우 개체 생성 성능은 실제로 문제가되지 않습니다!
Qw3ry

13

약간 다른 솔루션 :

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

            var fileContent = ""

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

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

어떤 이유로 이것은 나를 위해 작동하지 않았습니다. 클래스를 명시 적으로 호출하는 것만 작동했습니다. 다른 사람을 위해 추가하는 것뿐입니다. 나는 그것이 tornadofx와 관련이 있다고 생각합니다
nmu

에 테스트 입력 파일을 생성 한 후 /src/test/resources, this.javaClass.getResource("/<test input filename>")같은 예상했다. 위의 솔루션에 감사드립니다.
jkwuc89

fileContent가 String이 아니고 더미 개체를 만들지 않는 경우 어떻게해야합니까?
minizibi

1
여기서는 경로 앞의 슬래시가 필수 인 것처럼 보이지만 Java에서는 일반적으로 생략합니다.
cakraww

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

5

Kotlin + Spring 방식 :

@Autowired
private lateinit var resourceLoader: ResourceLoader

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

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

4

Google Guava 라이브러리 리소스 클래스 사용 :

import com.google.common.io.Resources;

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

그것은 자원이 발견되지 않는 경우 Guave 파일 이름을보고 있다는 좋은 - 더 나은 문제 해결을 위해
니시

1

이것이 내가 선호하는 방법입니다.

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

0

File 클래스가 유용 할 수 있습니다.

import java.io.File

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

3
이 대답은 잘못된 것입니다. "리소스"는로드하지 않지만 클래스 경로 대신 파일 시스템에서 직접 파일을로드합니다. jar 파일에서 파일을로드하는 대신 존재하지 않는 파일을 참조하려고하므로 애플리케이션이 어셈블 된 후에는 더 이상 작동하지 않습니다.
Ben

@ben 귀하의 의견에 감사드립니다. 질문은 kotlin Spek 테스트에서 리소스에서 파일을 읽는 것에 관한 것입니다.
Krzysztof Ziomek
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.