我是Java的新手,下面是我的Java文件。当我退出这个Java程序时,出现了java.lang.IndexOutOfBoundsException: Index: 4, Size: 4
这样的异常。
@Service public class TEImporter{ private final static Logger log = LoggerFactory.getLogger(TEImporter.class); //Tabellenname auf Spalten in der Tabelle Map < String, List < ColumnData >> columnDataCache = new HashMap < > (); private final JdbcTemplate jdbcTemplate; public TEImporter(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } /** * Be careful: Deletes all the data from the given table. * @param tableName the name of the table the data of which should be deleted. */ public void deleteTableData(String tableName) { jdbcTemplate.update("delete from " + tableName); } public void importFile(BufferedReader bufferedReader, String tableName, String fileName, Map < Integer, Function < String, String >> COLUMN_TYPE_MAPPINGS, Map < String, Function < String, String >> COLUMN_NAME_MAPPINGS) throws IOException { importFile(bufferedReader, tableName, fileName, COLUMN_TYPE_MAPPINGS, COLUMN_NAME_MAPPINGS, new ArrayList < > ()); } public void importFile(BufferedReader bufferedReader, String tableName, String fileName, Map < Integer, Function < String, String >> COLUMN_TYPE_MAPPINGS, Map < String, Function < String, String >> COLUMN_NAME_MAPPINGS, List < FixedValue > fixedValues) throws IOException { String firstLine = bufferedReader.readLine(); List < String > headings = Splitter .on(";") .trimResults() .splitToList(firstLine) .stream() .map(str - > str.replace("XXX-", "")) .map(str - > str.replace("-", "")) .map(str - > str.replaceAll("\\.", "")) .map(str - > str.equals("ORDER") ? "ORDERID" : str) // to work for ORDER columns in CSV files .map(String::toUpperCase) .filter(str - > str.length() > 0) // to suppress empty columns at the end of the line .collect(toList()); List < ColumnData > columnData = getColumns(tableName) .stream() .filter(cd - > !cd.getName().equals("SYSTEM_INSERTED_AT") && !cd.getName().equals("DATEINAME")) .collect(toList()); List < String > columnNames = columnData.stream().map(ColumnData::getName).collect(toList()); //Nur Spalten, die sowohl in der Datenbank als auch in der CSV-Datei enthalten sind, werden verarbeitet List < String > matchingColumns = intersection(headings, columnNames); List < String > columnsInDbButNotInCsv = subtract(columnNames, headings); columnsInDbButNotInCsv = subtract(columnsInDbButNotInCsv, fixedValues.stream().map(f - > f.getColumnName()).collect(toList())); columnsInDbButNotInCsv.forEach(s - > log.warn("Spalte '" + s + "' in Datenbank vorhanden, wird jedoch nicht in der CSV bereitgestellt")); //Index to columnData Map < Integer, ColumnData > columnsToInsert = new HashMap < > (); for (String column: matchingColumns) { columnsToInsert.put(headings.indexOf(column), columnData.stream().filter(cd - > cd.getName().equals(column)).findAny().get()); } int counter = 0; while (true) { String line = bufferedReader.readLine(); if (line == null) { break; } counter++; List < String > columns = Splitter .on(";") .splitToList(line); StringBuilder columnSqlFragment = new StringBuilder(); StringBuilder valuesSqlFragment = new StringBuilder(); for (int i = 0; i < headings.size(); i++) { String columnName = headings.get(i); String value = columns.get(i); if (!columnsToInsert.containsKey(i)) { continue; } if (i != 0) { columnSqlFragment.append(", "); valuesSqlFragment.append(", "); } int columnType = columnsToInsert.get(i).getType(); java.util.function.Function < String, String > mapping = COLUMN_NAME_MAPPINGS.containsKey(columnName) ? COLUMN_NAME_MAPPINGS.get(columnName) : COLUMN_TYPE_MAPPINGS.get(columnType); if (mapping == null) { throw new IllegalStateException("Kein Mapping für Spalte mit dem Namen " + columnName + " aus der Tabelle " + tableName + " mit Typ " + columnType + " gefunden"); } columnSqlFragment.append("\"" + columnName + "\""); valuesSqlFragment.append(mapping.apply(value)); } for (FixedValue fv: fixedValues) { columnSqlFragment.append(", "); columnSqlFragment.append(fv.getColumnName()); valuesSqlFragment.append(", "); valuesSqlFragment.append(fv.getValueSQLFragment()); } String sql = "insert into " + tableName + " (SYSTEM_INSERTED_AT, DATEINAME, " + columnSqlFragment + ") VALUES (sysdate, '" + fileName + "', " + valuesSqlFragment + ")"; log.info("Insert values to table" + sql); jdbcTemplate.update(sql); } log.info(counter + " Zeilen erfolgreich eingelesen."); } private List < ColumnData > getColumns(String tableName) { if (columnDataCache.containsKey(tableName)) { return columnDataCache.get(tableName); } List < ColumnData > result = new ArrayList < > (); try (Connection connection = jdbcTemplate.getDataSource().getConnection()) { ResultSet rs = connection.getMetaData().getColumns(null, null, tableName, null); boolean anyResults = false; while (rs.next()) { anyResults = true; String columnName = rs.getString(4).toUpperCase(); int type = rs.getInt(5); result.add(new ColumnData(columnName, type)); } columnDataCache.putIfAbsent(tableName, result); if (!anyResults) { throw new RuntimeException("Could not retrieve columns for table " + tableName); } return result; } catch (SQLException e) { throw new RuntimeException(e); } } }
我已经找出我出错的原因。
当我在普通文本编辑器中打开此csv文件时,我看不到数据有任何问题。但是,当我尝试在Ubuntu的VI编辑器中打开文件时,我可以看到存在^ M行字符,这是导致异常的原因。当我编辑文件并删除^ M并再次运行程序时,它的工作正常,并将数据插入表中。
这是Windows PC上的换行符,在基于VIM的编辑器中被读取为^ M,我从Windows获取此文件,并在ubuntu中阅读。
下面是我文件中的数据,在这里我可以看到^ M,它位于索引4。
我在Java中看到replaceAll
函数,但我不知道如何使用它以及我到底需要在哪里使用它。我只需要删除^M
并读取文件即可。请帮助
我是Java的新手,下面是我的Java文件。当我退出这个Java程序时,我得到一个异常,如java.lang.IndexOutOfBoundsException:索引:4,大小:4. @Service公共类...
只需将您的while循环更改为此,就可以最小化对代码的更改,以实现您的情况下的全部替换方法;