web-dev-qa-db-ja.com

Java-Apache.commons.csvを使用してCSVファイルを書き込む

JavaのApache.commons.csvライブラリ を使用しています。私はこのコードでウェブページからCSVファイルを読んでいます:

InputStream input = new URL(url).openStream();
        Reader reader = new InputStreamReader(input, "UTF-8");

        defaultParser = new CSVParser(reader, CSVFormat.DEFAULT);
        excelParser = new CSVParser(reader, CSVFormat.Excel.withHeader()); 

        defaultParsedData = defaultParser.getRecords();
        excelParsedData = excelParser.getRecords();

ただし、このライブラリで、このファイルを開いて後で読み取るために、このファイルを自分のコンピューターに簡単に書き込む方法が見つかりません。

このコードを試してファイルを保存しました。

String outputFile = savePath+".csv";
        CSVPrinter csvFilePrinter = null;
        CSVFormat csvFileFormat = CSVFormat.Excel.withHeader();
        FileWriter fileWriter = new FileWriter(outputFile);
        csvFilePrinter = new CSVPrinter(fileWriter, csvFileFormat);

        for (CSVRecord csvRecord : excelParser) {
            for(String dataPoint: csvRecord){
                csvFilePrinter.print(dataPoint);
            }
            csvFilePrinter.print('\n');
         }

        fileWriter.flush();
        fileWriter.close();
        csvFilePrinter.close();

ただし、このコードでファイルを読み取ろうとすると、何も出力されません。

InputStream input = new FileInputStream(cvsFilePath);
        Reader reader = new InputStreamReader(input, "UTF-8");

        CSVParser load = new CSVParser(reader, CSVFormat.Excel);
        //TEST THAT IT WORKED
        Java.util.List<CSVRecord> testlist = load.getRecords();
        CSVRecord dataPoint = testlist.get(0);
        System.out.println("print: " + dataPoint.get(0));

これは「print:」を出力するだけです。

System.out.println("print: " + dataPoint.get(1));

それは

スレッド「メイン」の例外Java.lang.ArrayIndexOutOfBoundsException:1

保存したCSVファイルをメモ帳で開くと、空白行が表示され、次のようになります。

2016-03-04,714.98999,716.48999,706.02002,710.890015,1967900,710.890015、 ""、2016-03-03,718.679993,719.450012,706.02002,712.419983,1956800,712.419983、 ""、2016-03-02,719.00,720.00,712.00,718.849976、 1627800,718.849976」

6
jonbon

すべてのレコードを同じ行に印刷しているようです。

printRecords のような他のメソッドがより役立ちます:

String outputFile = savePath+".csv";
CSVPrinter csvFilePrinter = null;
CSVFormat csvFileFormat = CSVFormat.Excel.withHeader();
FileWriter fileWriter = new FileWriter(outputFile);
csvFilePrinter = new CSVPrinter(fileWriter, csvFileFormat);

csvFilePrinter.printRecords(excelParser.getRecords());


fileWriter.flush();
fileWriter.close();
csvFilePrinter.close();
9
Arnaud

Arnaudによる回答 は正しくて良いです。これは、より短く、より現代的なバリエーションです。

ここに私達:

  • PathFile 、および Files モダンJavaファイル処理の作業を簡単にします。
  • BufferedWriter を使用すると、大量のデータでパフォーマンスが向上します。
  • 使用する 文字エンコード を指定します。通常 TF-8 が最適です。わからない場合は これを読んでください
  • ファイル関連の例外に必要な try-catches を含めます。
  • try-with-resources 構文を追加して、ファイルを自動的に閉じます。
  • バッファリングされたライターはBufferedWriterCSVPrinterの自動クローズの一部として自動的にフラッシュされるため、明示的なフラッシュをスキップします。 Javadocを引用するには、 Java.io.Writer::close 「ストリームを閉じて最初にフラッシュします。」を呼び出します。

コード:

CSVFormat format = CSVFormat.Excel.withHeader();
Path path = Paths.get( savePath + ".csv";
try (
        BufferedWriter writer = Files.newBufferedWriter( path , StandardCharsets.UTF_8 ) ;
        CSVPrinter printer = new CSVPrinter( writer , format ) ;
)
{
    printer.printRecords( excelParser.getRecords() );
} catch ( IOException e )
{
    e.printStackTrace();
}
1
Basil Bourque

FileWriterではなくCSVPrinterをフラッシュして閉じようとしましたか?

0
Ion Freeman