含NUL字符的CSV文件无法通过SuperCSV解析的问题咨询
NUL字符导致SuperCSV解析失效的问题分析与解决
什么是NUL字符?
NUL字符是ASCII编码里的0x00(对应Unicode的\u0000),属于不可见的控制字符,原本用于C语言这类系统标记字符串结束,但正常UTF-8文本文件里不应该出现这个字符。
为什么会出现NUL字符?
常见诱因包括:
- 数据源生成错误:程序写入CSV时误写了内存空值、二进制数据混入文本流;
- 文件传输损坏:FTP模式错误(二进制/文本混淆)、网络丢包导致乱码;
- 数据库导出bug:部分导出工具处理特殊字段时会输出无效NUL字符;
- 工具异常:大文件编辑或转换时,部分工具可能产生这类无效字符。
为什么NUL字符会让你的解析彻底失效?
看你的SuperCSV配置:
private static final CsvPreference CSV_PREFERENCE = new CsvPreference.Builder('\u0000', '|', "\n").build();
这里有个致命错误:你把CSV的引号字符(Builder第一个参数)设成了NUL字符!
SuperCSV的CsvPreference.Builder参数顺序是(引号字符, 分隔符, 换行符)。当CSV内容里出现NUL字符时,SuperCSV会把它当成引号的开始/结束标记——而引号包裹的内容里,分隔符|和换行符\n都会被当作普通文本处理,不会触发行分割和列分割。结果就是第三行之后的所有内容都被合并成一行,列数从13变成33,直接触发列数不匹配的错误。
修复方案
1. 紧急修正CsvPreference配置
先把引号字符改成正常值:
- 如果你的CSV用双引号包裹字段(标准CSV格式),用这个配置:
private static final CsvPreference CSV_PREFERENCE = new CsvPreference.Builder('"', '|', "\n").build();
- 如果你的CSV根本不用引号包裹字段,就选一个绝对不会在内容里出现的字符(比如罕见的控制字符
\u0001):
private static final CsvPreference CSV_PREFERENCE = new CsvPreference.Builder('\u0001', '|', "\n").build();
2. 预处理移除NUL字符
在解析前先把所有NUL字符过滤掉,避免干扰:
// 读取时直接过滤NUL字符的示例 try (BufferedReader reader = new BufferedReader(new InputStreamReader(yourInputStream, StandardCharsets.UTF_8))) { String rawLine; while ((rawLine = reader.readLine()) != null) { // 替换掉所有NUL字符 String cleanedLine = rawLine.replace("\u0000", ""); // 把cleanedLine传入SuperCSV解析,或者写入临时文件后再解析 } }
3. 从源头解决
联系CSV文件的生成方,排查NUL字符的产生原因,从源头杜绝这类无效字符的出现,避免后续重复踩坑。
内容的提问来源于stack exchange,提问作者alex_t
相关产品推荐
相关产品推荐

