我正在尝试使用jackson读取csv文件,但每当我真正去声明文件时,我都会得到以下异常:
IllegalStateException: classLoader.getResource("/src/integTest/testdata/Tests.csv") cannot be null
import com.fasterxml.jackson.databind.MappingIterator
import com.fasterxml.jackson.dataformat.csv.CsvMapper
import java.io.File
class CsvReader(private val fileName: String, private val testCase: TestCase) {
fun readCsv() {
// configure schema and reader
val mapper = CsvMapper()
val schema = mapper.schemaFor(testCase.javaClass)
val objectReader = mapper.readerFor(testCase.javaClass).with(schema)
//TODO this returns: java.lang.IllegalStateException: javaClass.getResource(fileName) must not be null
val reader = File(javaClass.getResource(fileName).file).reader()
//read file
val mappingIterator: MappingIterator<TestCase> = objectReader.readValues(reader)
while (mappingIterator.hasNext()) {
//TODO get fields from read and return a TestCase Object
println(mappingIterator.next())
}
}
我使用以下文件路径作为参数初始化类:
var FILE_NAME: String = "/src/integTest/kotlin/testdata/testCase.csv"
其他人遇到过这个问题吗?
答案 0 :(得分:2)
Gradle似乎在src / resources目录中寻找文件。
另外kotlin似乎没有与java很好地配合,所以我添加了Jackson Kotlin模块
使用泛型,因此代码可以在其他地方重复使用。现在似乎工作得很好。
这是新代码:
import com.fasterxml.jackson.databind.MappingIterator
import com.fasterxml.jackson.dataformat.csv.CsvMapper
import com.fasterxml.jackson.dataformat.csv.CsvSchema
import com.fasterxml.jackson.module.kotlin.KotlinModule
import org.springframework.core.io.ClassPathResource
inline fun <reified T> readCsv(filename: String): List<T> {
// configure mapper, schema and reader
val mapper = CsvMapper().apply { registerModule(KotlinModule()) }
val bootstrapSchema = CsvSchema.emptySchema().withHeader()
val objectReader = mapper.readerFor(T::class.java).with(bootstrapSchema)
//Read File and produce list from CSV
ClassPathResource(filename).inputStream.use {
val mappingIterator: MappingIterator<T> = objectReader.readValues(it)
val items = mutableListOf<T>()
mappingIterator.forEach { items.add(it) }
return items.toList()
}
}
答案 1 :(得分:1)
File(javaClass.getResource(fileName).file).reader()
这是有问题的代码。您正在尝试将资源作为文件读取 - 但资源不是文件。它可能存储在您的文件系统中,可能打包在JAR文件中等 - 这就是当您调用Class.getResource
时Java返回URL
而不是File
的原因。
相反,您应该使用Class.getResourceAsStream
方法并将其转换为读者:
javaClass.getResourceAsStream(fileName)?.let { InputStreamReader(it) }
请注意,如果找不到资源,getResourceAsStream
可能会返回null。
答案 2 :(得分:0)
下面的代码有帮助,
fun getResource(fileName: String): String {
val clazzLoader = this::class.java.classLoader
val stream = clazzLoader.getResourceAsStream(fileName)
val reader = stream.bufferedReader()
if (!Objects.isNull(reader)) {
val data = reader.readText()
reader.close()
return data
}
throw RuntimeException("The requested file $fileName not found")
}