1

まず第一に、私はJavaが初めてで、次の問題について助けが必要でした.

何百万ものレコードを含む Java リストがあります。このデータ一覧を CSV ファイルとしてエクスポートしたいと考えています。以下は、データを読み取るために作成した関数ですが、何百万ものレコードで失敗します。これを行うためのより良い方法を提案してください。

 private String generateCsvData(List<Map<String, Object>> rows) {

    String output = reportService.getReportHeadder();

    for (Map row : rows) {  

        output += (Long) row.get("branchId")
                + ","
                + StringEscapeUtils.escapeCsv((String) row.get("branches"))
                + ","
                + StringEscapeUtils.escapeCsv((String) row
                        .get("categoryName"))
                + ","
                + StringEscapeUtils.escapeCsv((String) row.get("products"))
                + ","
                + StringEscapeUtils.escapeCsv((String) row.get("emails"))
                + ","
                + StringEscapeUtils.escapeCsv((String) row
                        .get("contactAddress"))
                + ","
                + StringEscapeUtils.escapeCsv((String) row
                        .get("contactDet")) + ","
                + StringEscapeUtils.escapeCsv((String) row.get("url"))
                + "\n";

    }

    return output;
}
4

7 に答える 7

3

OpenCSVを使用することをお勧めします。CSV ファイルへのデータの読み書きを非常にうまくサポートしています。

于 2013-08-01T09:43:30.407 に答える
3

はい、簡単に喜んで。

一度にすべてのレコードをメモリに保持しようとすると、問題が発生します。あなたのマシンには非常に多くのメモリしかなく、その一部だけが JVM に割り当てられています。あなたがそれを埋めるとき、ゲームは終わりです。に既にデータがありMapます。その .csv 表現を同時に保存する必要がある場合、問題は 2 倍になります。

1 つの解決策は、一度に 1 行ずつストリーミングすることです。を反復処理してMap、データを 1 回だけ保存できます。

もう 1 つの解決策は、そのすべてのデータをリレーショナル データベース テーブルに格納することです。a を反復処理して、ResultSetその方法で結果をストリーミングできます。これで、メモリ要求が大幅に削減されました。

行を作成するメカニズムが良くありません。私はStringBuilder過剰連結を好むでしょう。

于 2013-08-01T09:45:32.040 に答える
2

問題は、非常に長い文字列を作成していて、それをファイルに書きたいということです。

さらに、連結するたびに新しい文字列を作成しています。これらの場合に使用しますStringBuilder

ストリームを使用して順次書き込む必要があります。基本的な ioは学習を開始するのに適したポイントです

于 2013-08-01T09:43:21.773 に答える
1

まず第一に、ループ内で文字列を構築する場合、文字列を連結しないでください。ただし、StringBuilder通常はパフォーマンスが向上し、多くの中間文字列でメモリを無駄にしないためです。

ただし、この場合、すべてをメモリに保持するのではなく、処理中にファイルに直接書き込むことをお勧めします。これにより、必要なメモリが削減されます。PrintWriterを確認するか、必要なことを既に実行しているライブラリを探します (例: OpenCSV )

于 2013-08-01T09:47:14.137 に答える
1

ファイルに書き込む前にすべてを文字列に保存しますが、ファイルを生成するときに行ごとにファイルに書き込むとどうなりますか?

于 2013-08-01T09:43:10.980 に答える
1

OpenCSVなどの CSV ライブラリを使用します。

ファイルを行ごとに処理できます。行を読み取ってから処理し、もう一度破棄します。そうすれば、ファイルの最大 1 行がメモリ内に存在します。

于 2013-08-01T09:43:57.860 に答える
0

Spring Batch のようなフレームワークを使用してみませんか。記録

于 2013-08-01T09:45:32.963 に答える