Import File In CSV Format For Kotlin

本文介绍如何在Kotlin中导入CSV格式的文件,特别强调了处理中文字符时可能出现的乱码问题。通过设置GBK编码来确保正确读取包含中文的CSV文件,避免导入时出现乱码。文中提供了测试案例和代码示例,说明了在不指定GBK编码时可能出现的问题以及解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

咱们昨天讲过了是如何导出CSV格式的文件,今天就简单唠叨下,CSV格式的文件是如何导入的;前些时候学习了kotlin语言,和java无缝混合开发还挺有意思的,若有Java版需求的请留言.额外再叨扰下,eclipse对kotlin支持不太友好,建议idea.

/**
 * 把csv文件转换成对象
 * @param clazz 需要转换的对象类
 * @param ins csv输入流
 * @param columnIndex 列描述所在行从0开始。
 * @param dataIndex  数据起始行从0开始。
 */
 fun <T> csvMap(clazz: Class<T> , ins: InputStream , columnIndex: Int , dataIndex: Int): List<T> {
    try {
	var lines = BufferedReader(InputStreamReader(ins , "GBK"))
         .use {it.lineSequence().map{String(it.toByteArray(Charsets.UTF_8))}.toList()}
	var rows = lines.size
	if (rows <= columnIndex || rows <= dataIndex) // do something
	//获取对象域名
	val columns =lines[columnIndex].split(COMMA_DELIMITER.toRegex()).dropLastWhile         
           { it.isEmpty() }.toTypedArray()
	var lists = mutableListOf<T>()
	var mapper = ModelMapper() // map convert object
	lines.drop(dataIndex).forEach {
		if (StringUtils.isBlank(it)) return@forEach
		val regex = Regex("(\\s)+") //处理空串防止下标越界("","  ")
		val dataColumns = it.split(COMMA_DELIMITER)
		var collect = dataColumns.stream().map {
			it.replace(SPECIAL_SYMBOLS , BLANK_STRING)
			}.filter {! it.matches(regex)}.toArray { Array(it) { BLANK_STRING } }
		if (collect.isEmpty()) return@forEach
		group(columns , collect).let { lists.add(mapper.map(it , clazz)) }
            }
		return lists
	} catch (ex: IOException) {
		//do something
	}
}

注意:代码块中GBK我是单独写出是要说明这很重要,如果导入文件中包含中文字符不加GBK导入结果会有乱码,这个问题困扰了我很久,后来查了很多文档,才知道在读取文件流时设置中文编码格式.

/**
 * 转map
 * @param keys 对象域名数组
 * @param values 对象数据数组
 */
fun group(keys: Array<String> , values: Array<String>): Map<String , String> = keys.zip(values).toMap()
const val SPECIAL_SYMBOLS = "`"
const val BLANK_STRING = ""
const val COMMA_DELIMITER = ","

测试使用:

fun main(args: Array<String>) {
    //获取文件
	var list = File("/tmp/测试下载文件7165987925830647393.csv").inputStream()
                .use { MapperUtil().csvMap(Test::class.java , it , 0 , 2) }
	println("$list")
}

测试使用需要说明的是,创建File时的文件地址是下载CSV格式文件测试结果略作修改源数据为:

注意: 第一行域名必须显式的存在,我们对下载CSV格式文件测试使用中代码片段作如下修改:

File file = utils.register("a","测试a", a -> a.getA()).register("b","测试b", a -> Objects.isNull(a.getB()) ? 2 : a.getB())
				.exportCsvFile("测试下载文件", list);//注意:文件名长度大于3

测试类:

class Test(var a: String = "" , var b: Int = 0) : Serializable {
		override fun toString(): String {
				return "Test(a='$a', b=$b)"
		}
}

测试结果:

[Test(a='王三', b=1), Test(a='d', b=2), Test(a='', b=3)]

去掉GBK的测试结果:

[Test(a='����', b=1), Test(a='d', b=2), Test(a='', b=3)]

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值