简体   繁体   English

Kotlin读取文件问题

[英]Kotlin reading a file issue

I am trying to read a csv file using jackson but whenever I actually go to declare the file, i get the below exception: 我正在尝试使用杰克逊读取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())
    }
}

I am initializing the class using the following file path as a parameter: 我正在使用以下文件路径作为参数来初始化类:

var FILE_NAME: String = "/src/integTest/kotlin/testdata/testCase.csv"

Anyone else ever encountered this issue? 其他人遇到过这个问题吗?

Gradle seemed to be looking for the file in a src/resources directory. Gradle似乎正在src / resources目录中寻找文件。

In addition kotlin didnt seem to play nicely with java so I added the Jackson Kotlin module 另外,kotlin似乎不能很好地与Java配合使用,因此我添加了Jackson Kotlin模块

Played around with generics so the code could be reusable elsewhere. 与泛型一起玩,因此代码可以在其他地方重用。 Seems to work nicely now. 看起来现在工作良好。

Here is the new code: 这是新代码:

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()
    }
}
File(javaClass.getResource(fileName).file).reader()

This is the problematic code. 这是有问题的代码。 You are trying to read a resource as a file - but a resource is no file. 您正在尝试将资源读取为文件-但是资源不是文件。 It might be stored in your file system, it might be packaged inside a JAR file etc - this is why Java returns a URL instead of a File when you call Class.getResource . 它可能存储在文件系统中,也可能打包在JAR文件中,等等-这就是为什么当您调用Class.getResource时Java返回URL而不是File

Instead, you should be using the Class.getResourceAsStream method and convert that to a reader: 相反,您应该使用Class.getResourceAsStream方法并将其转换为阅读器:

javaClass.getResourceAsStream(fileName)?.let { InputStreamReader(it) }

Note that getResourceAsStream might return null if the resource was not found. 请注意,如果找不到资源,则getResourceAsStream可能返回null。

The below code helps, 下面的代码有帮助,

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM