为什么我操作CSV新增列的Java函数会抛出IndexOutOfBounds异常?
CSV写入IndexOutOfBounds异常修复方案
核心问题原因
你代码里触发索引越界和逻辑错误的根因有4个:
- 未读取源CSV的表头行,while循环会把表头当成第一行数据处理,导致归一化数据取值错位,
dataAfterNormalization.get(j)容易超出列表长度 - 目标行新列的索引用了源文件当前行的列数,若源文件某行列数和表头列数不一致,会直接超出目标行数组的最大索引
writer.writeNext放在while循环外部,仅能写入最后一行数据,属于逻辑错误- 行数组
lineToBeWritten在循环外复用,会出现上一行数据残留的问题
修复后代码
import java.nio.charset.StandardCharsets; import com.opencsv.CSVReader; import com.opencsv.CSVWriter; // 类定义省略 private void writeDataToCSVDestinationFile(Path csvPath, Path destPath, String colToNormalize) throws IOException, CsvException { // 用try-with-resources自动关流,避免资源泄漏,指定UTF-8编码防止乱码 try (CSVWriter writer = new CSVWriter(new FileWriter(destPath.toString(), StandardCharsets.UTF_8)); CSVReader reader = new CSVReader(new FileReader(csvPath.toString(), StandardCharsets.UTF_8))) { // 读取源文件表头,替换外部传入的header变量,保证和实际文件结构一致 String[] header = reader.readNext(); if (header == null) { // 空文件直接返回 return; } // 生成目标文件表头 String[] headerDes = new String[header.length + 1]; System.arraycopy(header, 0, headerDes, 0, header.length); headerDes[header.length] = colToNormalize + "_scaled"; writer.writeNext(headerDes); // 提前获取归一化数据长度,做边界校验避免越界 int normalizedDataCount = dataAfterNormalization.size(); String[] currentSourceLine; int dataIndex = 0; while ((currentSourceLine = reader.readNext()) != null) { // 归一化数据不足时按需处理,可填默认值或者抛出异常,这里直接中断处理 if (dataIndex >= normalizedDataCount) { break; } // 每次循环新建行数组,避免旧数据残留 String[] lineToWrite = new String[headerDes.length]; // 复制源行数据,最多复制表头长度的列数,避免源行列数异常导致越界 int copyLen = Math.min(currentSourceLine.length, header.length); System.arraycopy(currentSourceLine, 0, lineToWrite, 0, copyLen); // 固定用表头长度作为新列的索引,不会触发数组越界 lineToWrite[header.length] = dataAfterNormalization.get(dataIndex).toString(); writer.writeNext(lineToWrite); dataIndex++; } } }
额外说明
- 如果你的
dataAfterNormalization长度和CSV数据行数不一致,可以根据业务需求调整不足时的处理逻辑,比如给不足的行填空字符串 - 如果你确定源CSV所有行的列数都和表头一致,可以去掉列数校验逻辑
内容的提问来源于stack exchange,提问作者shahed aa
相关产品推荐
相关产品推荐

