4

プロジェクトでは、実行前に列がわからない CSV ファイルを処理する必要があります。CSV ファイルは完全に有効です。いくつかの異なるファイルに対して単純なタスクを何度も実行するだけで済みます。列の値を分析する必要があるため、CSV ファイルを操作するためにライブラリを使用する必要があります。簡単にするために、列の数に関係なく、すべてのファイルに日付列を追加するなどの簡単なことを行う必要があると仮定しましょう。他のタスクにもライブラリを使用しているため、Super CSV でそれを実行したいと考えています。

私が苦労しているのは、より概念的な問題です。列数が事前にわからないと、ファイルの処理方法がわかりません。任意の CSV ファイルをマップする POJO をどのように定義すればよいのか、またはファイルに含まれる列とその数がわからない場合にセル プロセッサをどのように定義すればよいのかわかりません。列の数に一致する Cell プロセッサを動的に作成するにはどうすればよいですか? たとえば、CSV ファイルのヘッダーに基づいて POJO を定義するにはどうすればよいですか?

products.csv と address.csv の 2 つの CSV ファイルがある場合を考えてみましょう。同じことを行う 2 つの異なるメソッド (addDateColumnToProduct() と addDateColumnToAddress() など) を記述することなく、両方のファイルに今日の日付を含む日付列を追加するとします。

製品.csv:

name, description, price
"Apple", "red apple from Italy","2.5€" 
"Orange", "orange from Spain","3€"

アドレス.csv:

firstname, lastname
"John", "Doe"
"Coole", "Piet"

CSV ファイルのヘッダー情報に基づいて、製品の CSV をマップする POJO を定義するにはどうすればよいですか? セルプロセッサーについても同じ質問ですか? product.csv など、基本的にコンストラクター用の適切な量のパラメーターを持つ非常に単純なセル プロセッサを定義するにはどうすればよいでしょうか。

CellProcessor[] processor = new CellProcessor[] { 
    null,
    null,
    null
};

address.csv の場合:

CellProcessor[] processor = new CellProcessor[] { 
    null,
    null
};

これは可能ですか?これを達成するために私は間違った道を進んでいますか?

編集 1: 1つのファイルに可変列を持つ CSV ファイルを処理できるソリューションを探していません。実行時に任意の CSV ファイルを処理できるかどうか、つまり、実行時に CSV ファイルに含まれるヘッダー情報のみに基づいて POJO を作成できるかどうかを調べようとしています。csv ファイルに含まれる列数を事前に知らずに。

@babaからの回答とコメントに基づく解決策

private static void readWithCsvListReader() throws Exception {

        ICsvListReader listReader = null;
        try {
                listReader = new CsvListReader(new FileReader(fileName), CsvPreference.TAB_PREFERENCE);

                listReader.getHeader(true); // skip the header (can't be used with CsvListReader)
                int amountOfColumns=listReader.length();
                CellProcessor[] processor = new CellProcessor[amountOfColumns];
                List<Object> customerList;

                while( (customerList = listReader.read(processor)) != null ) {
                        System.out.println(String.format("lineNo=%s, rowNo=%s, customerList=%s", listReader.getLineNumber(),
                                listReader.getRowNumber(), customerList));
                }

        }
        finally {
                if( listReader != null ) {
                        listReader.close();
                }
        }
}
4

2 に答える 2

1

これは非常に一般的な問題であり、Internetz には Super Csv ページを含む複数のチュートリアルがあります。

http://supercsv.sourceforge.net/examples_reading_variable_cols.html

この行が言うように:

以下に示すように、read() を呼び出した後、executeProcessors() メソッドを呼び出すことで、セル プロセッサを実行できます。これは CSV の行を読み取った後に行われるため、(listReader.length() を使用して) 列の数を確認し、正しい数のプロセッサを指定する機会があります。

于 2014-02-09T11:42:50.477 に答える