4

バグを見つけたと思います。あるいはそうではないかもしれませんが、SuperCSVはそれをうまく処理できません。

MapReaderを使用して41列のCSVファイルを解析しています。しかし、私はそのCSVを取得しています-そして、CSVを提供するWebサービスは1行を台無しにします。「見出し」行は、41個のセルを持つタブ区切りの行です。

また、「間違った行」は、36個のセルを持つタブ区切りの行であり、内容は意味がありません。

これは私が使用しているコードです:


InputStream fis = new FileInputStream(pathToCsv);
InputStreamReader inReader = new InputStreamReader(fis, "ISO-8859-1");

ICsvMapReader mapReader = new CsvMapReader(inReader, new CsvPreference.Builder('"','\t',"\r\n").build());
final String[] headers = mapReader.getHeader(true);
Map<String, String> row;
while( (row = mapReader.read(headers)) != null ) {

    // do something


}

上記の行でmapReader.read(headers)を実行すると、例外が発生します。これは例外です:

org.supercsv.exception.SuperCsvException: 
the nameMapping array and the sourceList should be the same size (nameMapping length = 41, sourceList size = 36)
context=null
at org.supercsv.util.Util.filterListToMap(Util.java:121)
at org.supercsv.io.CsvMapReader.read(CsvMapReader.java:79)
at test.MyClass.readCSV(MyClass.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)

あなたは私が何をすべきだと思いますか?

1つの行が混乱しているという理由だけで、アプリケーション全体がクラッシュすることは望ましくありません。その行をスキップしたいと思います。

4

3 に答える 3

5

これは良い質問です!Super CSV 開発者として、Web サイトで例外処理の例をいくつか作成することを検討します。

シンプルに保ち、CsvListReader (列の数は関係ありません) を使用してから、自分でマップを作成するだけです。

public class HandlingExceptions {

    private static final String INPUT = 
        "name\tage\nTom\t25\nAlice\nJim\t44\nMary\t33\tInvalid";

    public static void main(String[] args) throws IOException {

        // use CsvListReader (can't be sure there's the correct no. of columns)
        ICsvListReader listReader = new CsvListReader(new StringReader(INPUT), 
            new CsvPreference.Builder('"', '\t', "\r\n").build());

        final String[] headers = listReader.getHeader(true);

        List<String> row = null;
        while ((row = listReader.read()) != null) {

            if (listReader.length() != headers.length) {
                // skip row with invalid number of columns
                System.out.println("skipping invalid row: " + row);
                continue;
            }

            // safe to create map now
            Map<String, String> rowMap = new HashMap<String, String>();
            Util.filterListToMap(rowMap, headers, row);

            // do something with your map
            System.out.println(rowMap);
        }
        listReader.close();
    }
}

出力:

{name=Tom, age=25}
skipping invalid row: [Alice]
{name=Jim, age=44}
skipping invalid row: [Mary, 33, Invalid]

Super CSV のUtilクラス (変更される可能性があります。実際には内部ユーティリティ クラスです) の使用に関心がある場合は、ここで提案したように 2 つのリーダーを組み合わせることができます。

をキャッチSuperCsvExceptionしてみることができますが、無効な数の列以上を抑制することになる可能性があります。キャッチすることをお勧めする唯一の Super CSV 例外 (ただし、セル プロセッサを使用していないため、状況には適用されません) はSuperCsvConstraintViolationException、ファイルが正しい形式であることを示していますが、データが期待される制約を満たしていないことを示しています。

于 2012-11-27T23:17:08.707 に答える
1

CSV ファイルに解析できないデータが含まれている場合は、どうすればよいかを自問する必要があります。これらの行をスキップすることはどれほど重要でしょうか。あるシナリオでは、それをドロップしても問題ない場合があります。他のシナリオでは、プロセス全体を停止して、最初にファイルを修正するようにユーザーに指示する方がよい場合があります。

どちらのシナリオも Super CSV で構築できると確信しています。その例外を処理し、前述のシナリオに適切に対応する必要があります。

于 2012-11-27T14:17:17.640 に答える
0

まあ、私はいくつかの解決策を思いつきましたが、それが最適だとは思いません。

while (true) {
    try {
        if ((row = mapReader.read(headers)) == null) {
            break;
        } else {
            // do something
        }
    } catch (SuperCsvException ex) {
        continue;
    }
}

アップデート

Exceptionで変更SuperCsvException

于 2012-11-27T14:23:57.590 に答える