Java中CSV与Web表格对比时数组越界问题求助
问题分析与修复方案
核心问题
你的代码出现索引越界,根源是错误地用字符串长度line.length()作为CSV列的循环条件——line.length()是当前行的字符总数(比如你看到的115),而不是CSV拆分后的列数。此外,循环嵌套逻辑混乱,导致CSV行和表格行的对应关系错位,还重复读取CSV行,最终触发数组越界。
具体问题点
- 外层循环
for (int col = 1; col < line.length();)完全错误,应该用CSV拆分后的cells.length来控制列遍历。 - 嵌套循环顺序错误:应该先遍历表格行,再对应遍历CSV行,而不是列循环嵌套行循环。
- 内部重复调用
br.readLine(),会跳过大量CSV行,导致后续读取的行和表格行不匹配。 - 每次循环都重新查找表格行
rows_table2 = mytable1.findElements(By.tagName("tr")),属于冗余操作,直接复用之前的rows_table1即可。 - List和数组都是0索引,代码中从1开始遍历虽然能运行,但容易混淆索引对应关系。
修正后的代码
WebElement mytable1 = driver.findElement(By.cssSelector("#dStocks1")); // 获取表格所有行 List<WebElement> tableRows = mytable1.findElements(By.tagName("tr")); int totalTableRows = tableRows.size(); String path = filePath; BufferedReader br = new BufferedReader(new FileReader(path)); System.out.println("\n CSV data: "); // 跳过CSV表头行 br.readLine(); // 遍历表格行(从索引1开始,跳过表格表头) for (int rowIdx = 1; rowIdx < totalTableRows; rowIdx++) { // 读取CSV的一行数据 String line = br.readLine(); if (line == null) { // 如果CSV行不足,直接终止循环 break; } // 拆分CSV行,处理带引号的列 String splitBy = ",(?=([^\"]|\"[^\"]*\")*$)"; String[] csvCells = line.split(splitBy); // 获取当前表格行的所有单元格 List<WebElement> tableCells = tableRows.get(rowIdx).findElements(By.tagName("td")); int totalTableCells = tableCells.size(); System.out.println("Number of cells In Row " + rowIdx + " are " + totalTableCells); // 遍历单元格(从索引1开始,根据你的输出调整,若表头在索引0则从0开始) for (int cellIdx = 1; cellIdx < totalTableCells; cellIdx++) { if (cellIdx >= csvCells.length) { // 防止CSV列数少于表格列数导致越界 System.err.println("Warning: CSV has fewer columns than table at row " + rowIdx); break; } String tableCellText = tableCells.get(cellIdx).getText(); // 去除CSV单元格的前后引号 String csvCellText = csvCells[cellIdx].replaceAll("^\"|\"$", ""); // 断言对比 assertEquals(tableCellText, csvCellText); System.out.print(" CELL: " + cellIdx + " " + csvCellText + "\n"); } System.out.println(" "); } // 关闭流 br.close();
关键优化说明
- 循环逻辑调整:先遍历表格行,再对应读取CSV行,保证行一一对应。
- 列循环条件修正:用
csvCells.length代替line.length(),避免字符数和列数混淆。 - 增加边界判断:在访问CSV数组前检查索引,防止列数不匹配导致越界。
- 冗余操作移除:复用已获取的表格行列表,避免重复查找DOM元素。
- 引号处理优化:用
replaceAll("^\"|\"$", "")更简洁地去除CSV单元格的前后引号。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

