Dart csv包解析含ä、ö等非ASCII字符CSV文件报错如何处理?
问题根因
你的报错并非来自csv第三方包,而是rootBundle.loadString方法的默认解码逻辑触发的:该方法默认使用UTF-8编码解析文件字节,当你的CSV文件是Latin1(ISO-8859-1,支持ä、ö等西欧字符)等非UTF-8编码时,会在文件读取阶段直接抛出格式异常,还没有进入csv包的处理流程。
csv包本身仅负责将已解码的字符串格式的CSV内容转换为List结构,不涉及编码解码逻辑,因此没有提供字符集设置项,这符合RFC4180的规范要求:字符集参数是文本传输/解析阶段的配置,不属于CSV格式转换的范畴。
解决方法
修改文件读取逻辑,指定和CSV文件匹配的编码解码即可,有两种实现方式:
方式1:直接给loadString指定编码(写法更简单)
import 'dart:convert'; Future<String> determineNewWord({String path}) async { // 按文件实际编码指定encoding参数,支持äö的西欧字符文件用latin1,UTF-8编码文件用utf8 final myData = await rootBundle.loadString(path, encoding: latin1); List<List<dynamic>> csvTable = const CsvToListConverter().convert(myData); String newWord = csvTable[Random().nextInt(csvTable.length)].first; return newWord.toUpperCase(); }
方式2:先读原始字节再手动解码(适配自定义编码场景)
如果你的文件是GBK等dart:convert内置不支持的编码,可以先读取原始字节,配合第三方编码解析包解码后再传给csv包:
import 'dart:typed_data'; import 'package:flutter/services.dart'; Future<String> determineNewWord({String path}) async { final ByteData byteData = await rootBundle.load(path); final Uint8List bytes = byteData.buffer.asUint8List(); // 此处替换为对应编码的解码逻辑即可 final String myData = latin1.decode(bytes); List<List<dynamic>> csvTable = const CsvToListConverter().convert(myData); String newWord = csvTable[Random().nextInt(csvTable.length)].first; return newWord.toUpperCase(); }
补充说明
如果不确定CSV文件的编码格式,可以用VS Code等文本编辑器打开文件,右下角状态栏会直接显示当前文件的编码,对应选择解码器即可。
内容的提问来源于stack exchange,提问作者jonasxd360
相关产品推荐
相关产品推荐

