我正在编写一个简单的导入应用程序,需要读取CSV文件,在网格中显示结果并在另一个网格中显示CSV文件的损坏行。
是否有任何内置的lib或任何简单的pythonic式方式?
我在Android上做这件事。
答案 0 :(得分:4)
使用opencsv。
这就像读取CSV文件的魅力一样。
就记录损坏的行而言,您可以使用此逻辑来执行此操作。
while(input.hasNextLine())
{
try
{
//execute commands by reading them using input.nextLine()
}
catch (ex: UserDefinedException)
{
//catch/log the exceptions you're throwing
// log the corrupted line the continue to next iteration
}
}
希望这有帮助。
答案 1 :(得分:3)
我使用net.sourceforge.javacsv和我的Kotlin代码来解析CSV文件。它是一个“java”库,但在kotlin中,它就像
一样直接使用它val reader = CsvReader("/path/to/file.csv").apply {
trimWhitespace = true
skipEmptyRecords = true
readHeaders()
}
while (reader.readRecord()) {
// do whatever
}
答案 2 :(得分:3)
在易用性方面,kotlin编写的csv库更好。
例如,您可以使用下面创建的以下库以DSL方式编写代码:
https://github.com/doyaaaaaken/kotlin-csv
csvReader().open("test.csv") {
readAllAsSequence().forEach { row ->
//Do something with the data
println(row)
}
}
答案 3 :(得分:2)
坦白地说,使用现代Java功能在Kotlin中创建简单的阅读器非常容易,请选中此选项(记住以处理BOM:-)):
fun processLineByLine(csv: File, processor: (Map<String, String>) -> Unit) {
val BOM = "\uFEFF"
val header = csv.useLines { it.firstOrNull()?.replace(BOM, "")?.split(",") }
?: throw Exception("This file does not contain a valid header")
csv.useLines { linesSequence ->
linesSequence
.drop(1)
.map { it.split(",") }
.map { header.zip(it).toMap() }
.forEach(processor)
}
}
比您可以按以下方式使用它(取决于您的文件结构):
processLineByLine(File("./my-file.csv")) { row ->
println("UserId: ${row["userId"]}")
println("Email: ${row["email"]}")
}
答案 4 :(得分:1)
根据建议,使用opencsv很方便。这是一个最小的示例:
// You can of course remove the .withCSVParser part if you use the default separator instead of ;
val csvReader = CSVReaderBuilder(FileReader("filename.csv"))
.withCSVParser(CSVParserBuilder().withSeparator(';').build())
.build()
// Maybe do something with the header if there is one
val header = csvReader.readNext()
// Read the rest
var line: Array<String>? = csvReader.readNext()
while (line != null) {
// Do something with the data
println(line[0])
line = csvReader.readNext()
}
如docs所示,当您不需要分别处理每一行时,代码将变得更加整洁:
val values = CSVReaderHeaderAware(FileReader("filename.csv")).readMap()
答案 5 :(得分:1)
如果您更喜欢为每一行使用自己的数据类,您应该查看我的解决方案 https://github.com/gmuth/ipp-client-kotlin/blob/master/src/main/kotlin/de/gmuth/csv/CSVTable.kt
data class User(
val name: String,
val phone: String,
val email: String
) {
constructor(columns: List<String>) : this(
name = columns[0],
phone = columns[1],
email = columns[2]
)
}
CSVTable.print(FileInputStream("users.csv"))
val userList = CSVTable(FileInputStream("users.csv"), ::User).rows
答案 6 :(得分:0)
我知道我来晚了,但是最近我在解析CSV时遇到了问题,似乎没有足够的库可以满足我的需求,所以我创建了自己的Kotlin CSV stream。
此库很特殊,因为它不会在无效输入上引发异常,而是返回结果,这在某些情况下可能有用。