如何在没有javaClass的情况下从资源中读取文本文件

How to read a text file from resources without javaClass

我需要阅读一个带有 readLines() 的文本文件,我已经找到了 ,但是答案中的代码总是使用 javaClass 的一些变体;它似乎只在 class 中工作,而我只使用一个没有声明 classes 的简单 Kotlin 文件。像这样写在语法上是正确的,但它看起来真的很难看,而且总是 returns null,所以它一定是错误的:

val lines = object {}.javaClass.getResource("file.txt")?.toURI()?.toPath()?.readLines()

当然我也可以像这样指定原始路径,但我想知道是否有更好的方法:

val lines = File("src/main/resources/file.txt").readLines()

Kotlin 没有自己获取资源的方法,所以你必须使用 Java 的方法 Class.getResource。您不应该假设资源是文件(即不要使用 toPath),因为它很可能是 jar 中的条目,而不是文件系统中的文件。要读取资源,更容易将资源作为 InputStream 获取,然后从中读取行:

val lines = this::class.java.getResourceAsStream("file.txt").bufferedReader().readLines()

我不确定我的回复是否试图回答您的确切问题,但也许您可以这样做:

我猜在最终用例中,文件名将是动态的——不是静态声明的。在这种情况下,如果您有权访问或知道该文件夹的路径,您可以这样做:


// Create an extension function on the String class to retrieve a list of 
// files available within a folder. Though I have not added a check here
// to validate this, a condition can be added to assert if the extension
// called is executed on a folder or not
fun String.getFilesInFolder(): Array<out File>? = with(File(this)) { return listFiles() }

// Call the extension function on the String folder path wherever required
fun retrieveFiles(): Array<out File>? = [PATH TO FOLDER].getFilesInFolder()

一旦你有了对 List<out File> 对象的引用,你就可以这样做:


// Create an extension function to read 
fun File.retrieveContent() = readLines()
// You can can further expand this use case to conditionally return
// readLines() or entire file data using a buffered reader or convert file
// content to a Data class through GSON/whatever.
// You can use Generic Constraints 
// Refer this article for possibilities
// https://kotlinlang.org/docs/generics.html#generic-constraints


// Then simply call this extension function after retrieving files in the folder.
listOfFiles?.forEach { singleFile -> println(singleFile.retrieveContent()) }

感谢提供正确的文件读取方式。目前,不使用 javaClass 或类似结构从资源中读取文件似乎是不可能的。

// use this if you're inside a class
val lines = this::class.java.getResourceAsStream("file.txt")?.bufferedReader()?.readLines()

// use this otherwise
val lines = object {}.javaClass.getResourceAsStream("file.txt")?.bufferedReader()?.readLines()

根据我发现的其他类似问题,第二种方式也可能在 lambda 中工作,但我没有测试过。注意从这一点开始需要 ?. 运算符和 lines?.let {} 语法,因为 getResourceAsStream() returns null 如果没有找到具有给定名称的资源.