2

我使用CsvJDBC从 CSV 读取数据。我从 Web 服务请求中获取 CSV,因此没有从文件中加载。我调整这些属性:

Properties props = new java.util.Properties();
props.put("separator", ";"); // separator is a semicolon
props.put("fileExtension", ".txt"); // file extension is .txt
props.put("charset", "UTF-8"); // UTF-8

我的 sample1.txt 包含这些数据:

code;description
c01;d01
c02;d02

我的 sample2.txt 包含这些数据:

code;description
c01;d01
c02;d0;;;;;2

从 CSV 中删除标题对我来说是可选的。但对我来说不是可选的更改分号分隔符。

编辑:我的查询resultSetSELECT * FROM myCSV

我想阅读codesample1.txt 和 sample2.txt 中的列:

resultSet.getString(1)

并阅读description带有许多分号 ( d0;;;;;2) 的整列。是否可以使用 CsvJdbc 驱动程序或需要更改驱动程序?

谢谢你的任何建议!

4

5 回答 5

3

当您有混乱、无效的输入时会出现这个问题,您需要尝试解释这些输入,这是由只处理干净输入的太高级包读取的。一个类似的例子是尝试使用 XML 解析器读取任意 HTML - 接近,但没有雪茄。

你可以猜到我要去哪里:你需要预处理你的输入。

如果您可以对数据做出一些假设,预处理可能会非常容易 - 例如,如果保证第一列中没有带引号的分号。

于 2013-10-17T17:01:05.650 回答
3

你可以试试supercsv。我们已经在我们的项目中实施了这样的解决方案。可以在http://supercsv.sourceforge.net/使用 CsvBeanReader 读取具有可变列数的 CSV 文件中找到更多相关信息

于 2013-10-23T19:19:13.423 回答
3

最后,这个问题在没有 CSVJdbc 或 SuperCSV 驱动程序的情况下解决了。这些驱动程序工作正常。有可能的 CSV 文件形式的查询数据和许多功能内容。就我而言,我不需要来自 CSV 的查询数据。不幸的是,有时描述列包含一个或多个分号,它是我的分隔符。

首先,我检查@Maher Abuthraa 的回答代码并修改为:

private String createDescriptionFromResult(ResultSet resultSet, int columnCount) throws SQLException {

        if (columnCount > 2) {
            StringBuilder data_list = new StringBuilder();

            for (int ii = 2; ii <= columnCount; ii++) {
                data_list.append(resultSet.getString(ii));
                if (ii != columnCount)
                    data_list.append(";");
            }
            // data_list has all data from all index you are looking for ..
            return data_list.toString();
        } else {
            // use standard way
            return resultSet.getString(2);
        }
    } 

循环从 2 开始,因为 1 列是代码,只有描述列内容很多分号。CSVJdbc 驱动程序按分隔符拆分列;,这些分号从列数据中消失。因此,除了最后一列外,我在描述中显式添加分号,因为它与我的情况无关。

此代码工作正常。但没有解决我所有的问题。当我调整 CSV 标题中的两列时,行中出现错误,其内容超过两个分号。所以我尝试调整忽略标题或将许多列名(或简单;)添加到标题中。在 superCSV 中忽略 headers 选项工作正常。

我的同事的意见是:您不需要 CSV 驱动程序,因为如果分隔符有时是相关数据,请尝试加载不是 CSV 的 CSV。

我认为我的同事是对的,我使用以下代码加载了 CSV 数据:

InputStream in = null;
try {
        in = new ByteArrayInputStream(csvData);

        List lines = IOUtils.readLines(in, "UTF-8");
        Iterator it = lines.iterator();
        String line = "";
        while (it.hasNext()) {
        line = (String) it.next();

        String description = null;
        String code = null;
        String[] columns = line.split(";");

        if (columns.length >= 2) {
            code = columns[0];
            String[] dest = new String[columns.length - 1];
            System.arraycopy(columns, 1, dest, 0, columns.length - 1);
            description = org.apache.commons.lang.StringUtils.join(dest, ";");
          (...) 
于 2013-10-25T07:28:45.127 回答
2

好的..如果列超过2,我的解决方案是读取所有字段...例如:

int ccc = meta.getColumnCount();
    if (ccc > 2) {
        ArrayList<String> data_list = new ArrayList<String>();
        for (int ii = 1; ii < ccc; ii++) {
            data_list.add(resultSet.getString(i));
        }
        //data_list has all data from all index you are looking for ..
    } else {
        //use standard way 
        resultSet.getString(1);
    }
于 2013-10-17T10:43:36.650 回答
1

如果表被定义为具有与源中的分号一样多的列,忽略初始列定义,那么数据库驱动程序将自动使用多余的分号。

它们出现在最后一列中的最可能原因是解析器将行的余额返回给字段中的终止符。

简单地增加表中的列数以匹配输入中可能的最大值将避免在程序中进行自定义解析的需要。尝试:

code;description;dummy1;dummy2;dummy3;dummy4;dummy5
c01;d01
c02;d0;;;;;2

然后,附加的';' 解析器将正确使用分隔符。

于 2013-10-26T20:48:47.650 回答