2016-04-15 32 views
4

JavaでApache Commons CSV 1.2を解析する37列のCSVファイルがあります。次のように私のセットアップコードは次のとおりです。ただしCSVの相違によるエラーの解析(Java with Apache Commons CSV)

Exception in thread "main" java.lang.IllegalArgumentException: Index for header 'Title' is 7 but CSVRecord only has 6 values! 
     at org.apache.commons.csv.CSVRecord.get(CSVRecord.java:110) 
     at launcher.QualysImport.createQualysRecords(Unknown Source) 
     at launcher.QualysImport.importQualysRecords(Unknown Source) 
     at launcher.Main.main(Unknown Source) 

//initialize FileReader object 
FileReader fileReader = new FileReader(file); 

//intialize CSVFormat object 
CSVFormat csvFileFormat = CSVFormat.DEFAULT.withHeader(FILE_HEADER_MAPPING); 

//initialize CSVParser object 
CSVParser csvFileParser = new CSVParser(fileReader, csvFileFormat); 

//Get a list of CSV file records 
List<CSVRecord> csvRecords = csvFileParser.getRecords(); 

// process accordingly 

私の問題は、私は私のターゲットディレクトリに加工し、私の構文解析プログラムを実行するためにCSVをコピーするとき、私は次のエラーを取得するということですファイルを自分のターゲットディレクトリにコピーして開いて保存してから、もう一度プログラムを試してみてください。 CSVを開いて保存すると、最後に必要なコンマが追加されますので、私のプログラムは読み込みに十分なヘッダーがないことを補うことはできません。

状況については、ここで保存した後/前のサンプルラインです:

(失敗)の前に: "データ"、 "データ"、 "データ"、 "データ"

(作業)した後、 "データ"、 "データ"、 "データ"、 "データ" ,,,,,,

私は値やエンコーディングを変更していませんし、MS-DOSや標準の.csv形式で保存するときの動作は同じです。また、私はテストでコピー/オープン/保存するためにExcelを使用しています。

使用する必要があるエンコードまたはフォーマットの設定はありますか?これをプログラムで解決できますか?

ありがとうございます!

EDIT#1:追加のコンテキストについては

、私は最初、元のファイルに空の行を表示するとき、それはちょうどこのような新しい行^ Mの文字があります。

^M 

した後にExcelで開いたり保存し、それは私の空のフィールドのすべての37で次のようになります。

,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,^M 

これは、Windowsのエンコーディングの不一致ですか?

答えて

1

おそらく、ファイルを最初に生成したものとの互換性の問題です。 Excelは、空白行を有効な行として、各列に空の文字列を使用し、他の行と一致する列の数を受け入れているようです。次に、列デリミタを使用してCSV規則に従ってそれを保存します。 (^ Mキャリッジリターン文字であり、マイクロソフトのシステムでは、テキストファイル内の行の末尾に改行文字の前に)

おそらく、あなたとの間に座って、あなた自身のReaderサブクラスを作成することにより、それに対処することができますFileReaderおよびCSVParserあなたの読者は行を読んで、それが空白の場合は、正しい数のカンマで行を返します。それ以外の場合はそのままそのまま返してください。例えば

class MyCSVCompatibilityReader extends BufferedReader 
    { 
    private final BufferedReader delegate; 

    public MyCSVCompatibilityReader(final FileReader fileReader) 
     { 
     this.delegate = new BufferedReader(fileReader); 
     } 

    @Override 
    public String readLine() 
     { 
     final String line = this.delegate.readLine(); 
     if ("".equals(line.trim()) 
      { return ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"; } 
     else 
      { return line; } 
     } 
    } 

インタフェースを実装する場合、正しく実装するためのその他の詳細情報がたくさんあります。他のすべてのメソッド(閉じる、準備、リセット、スキップなど)への呼び出しを渡す必要があり、さまざまな方法のそれぞれが正しく機能することを確認してください。ファイルが簡単にメモリに収まる場合は、ファイルを読み込んで固定バージョンを新しいStringWriterに書き込んでから、StringReaderをCSVParserに作成する方が簡単です。

+0

素晴らしい入力です。ありがとうございました。私はまた、RFC 4180がExcelが「不適合」のCSVファイルを保存する標準であることを読んだだけで、保存後にコンマが表示される理由です。私はプログラマチックに解決しなければならないので、私は自分の読者を実装するつもりです。 – corneria

-1

多分これを試してください: 与えられたファイルのパーサを作成します。 解析(ファイルファイル、文字セット、CSV形式)

//インポートをインポートするjava.nio.charset.StandardCharsets; //StandardCharsets.UTF_8

注:このメソッドは、内部で順番にコードを実行しているJVMのデフォルトのエンコーディングに依存しFileReader.FileReader(java.io.Fileの)を使用してFileReaderを作成。

+0

これは、欠落している列を追加することと何が関係していますか? – RealSkeptic

+0

とかallowMissingColumnNames? CSVFormat csvFileFormat = CSVFormat.DEFAULT.withHeader(FILE_HEADER_MAPPING).withAllowMissingColumnNames(); – user1176726

+1

推測しないでください。問題を調査して答えを知っていれば、答えてください。しかし、未確認の提案を投げるだけでは、スタックオーバーフローでは動作しません。また、あなたの答え、特にコードである部分をフォーマットすることになっています。 – RealSkeptic

-1

または、おそらくwithAllowMissingColumnNamesを試してみますか?

//intialize CSVFormat object 
CSVFormat csvFileFormat = CSVFormat.DEFAULT.withHeader(FILE_HEADER_MAPPING).withAllowMissingColumnNames(); 
+0

いいえ、それは列が名前なしでそこにあると推測します。私の列は存在しません。(ファイルを保存する前に) – corneria