0

私は、テキスト ファイルの解析 (ETL アプローチの適用) に関連する小さな開発プロジェクトに参加しています。ローカル マシンで正しく動作するデモ コードを作成しましたが、それを Apache Tomcat コンテナにデプロイすると、メモリ オーバーフローや型変換などに関連する多くのエラーが生成されます。

これは一般的な事実です:

これはファイル構造です(メモでは、各セルのデータ型とその他の関連情報が指定されています)。

RegisterType1は顧客ごとに 1 回だけ繰り返され、RegisterType2は 1 回以上繰り返され、RegisterType3RegisterType4は 1 回繰り返されることに注意してください。

また、レジスタ タイプごとに長さが異なることにも注意してください。たとえば、RegisterType1 は 12 フィールド、RegisterType2 は 10 フィールドなどです。

前に言ったように、私の現在のパーサーはコードが非常に悪いため、多くのエラーが発生します。これは実際のコードであり、これ(db 接続を作成してクエリを実行するクラス) です。

これは、解析が必要なテキスト ファイルの例です。

現在の開発環境 プラットフォーム:Java 6 コンテナ:Tomcat 7 VPSプロファイル:RAM 1.7GB、ストレージ:20GB、プロセッサ:(Intel(R) Xeon(R) CPU X5650 @ 2.67GHz、24コア)。

実際の問題:

  • パフォーマンスが悪い
  • メモリオーバーフロー
  • 解析エラー: データ型変換、フィールド間の区切り文字 (セミコロン) (例: ...Paris;Fran[ここにセミコロン]ce;...)

効率的で、正確で、高性能なパーサーを作成したいと考えています。

このトピックへの提案が必要です。優れたパーサーを作成する最良の方法はどれですか?

事前に情報をありがとう。

よろしく、

4

1 に答える 1

1

関連するコードをここに投稿してください。わかりました、私はあなたのためにこれのいくつかをします:

    BufferedReader reader = null;

    ArrayList< String> elements = new ArrayList< String>();

    try {
        reader = new BufferedReader(new FileReader(archivoFuenteDatos));
        String text = null;

        // repeat until all lines is read
        while ((text = reader.readLine()) != null) {
        ...
        elements.add(...);
        ...
    } catch(...) ...

    saveOnDB(elements);

そのような巨大なファイルを決して読まないでください。その場合、すべてのデータを同時にメモリに保持する必要があります。

  1. 最初に配列リストにコピーするのではなく、各エントリをデータベースに直接書き込んでみてください。これにより、OOM が修正されることが期待されます。

  2. コードをプロファイリングします。それが十分に速い場合は、完了です。

  3. 十分に高速でない場合は、ArrayList を作成します。それに初期容量を与えますnnデータベースに書き込む前に、そのリストにアイテムを読み込んでください。

編集:何か重要なことを見逃していなければ、あなたは自分のコードを 4 回コピーしました。投稿する前にリファクタリングしてください (コードが多すぎます)。たとえば、巨大なスイッチは次のようにリファクタリングできます。

        while ((text = reader.readLine()) != null) {
            String[] campos = text.replaceAll(" +", " ").split(";");
            int n;
            switch (text.charAt(0)) {
                case '1':
                case '2':
                case '3':
                    n = campos.length - 1;
                    break;
                case '4':
                    // what does this mean? It will always give 5!
                    // n = contarPuntoComas(text) == 6 ? 5 : 5;
                    n = 5;
                    break;
                default:
                    n= 0;
            }
            for (int i = 0; i < n; ++i) {
                 elements.add(campos[ i].trim());
            } // end for
        }
于 2013-03-13T20:28:58.617 に答える