2010-12-04 3 views
5

私は1つのcsvファイルを持っています。これは、スクリプトによって連続的に書かれています。行ごとにタイムスタンプとその他のデータを書き込みます。私は最初に最新のデータを読む必要があります。 現在、JavaでRandomAccessFileを使用して、逆の方法でファイルを読み取ります。しかし、書かれているように、私は新しいデータを優先して読む必要があります。私はどのタイムスタンプが送られているかを維持しており、作業を行っています。不要なスキャン操作が行われます。私のアプローチで提案が必要です:継続的に書かれているファイルを読む?

このシナリオに対処する方法はありますか?あなたは1が表示されたら、新しい行を読み込み、未処理の行のスタックにそれらをプッシュし、スレッド、およびスタックをポップし、逆に新しい行を処理し第二のスレッドを持つ検討することもでき、事前に

おかげで、

答えて

1

注文。

新しい行の処理に要する時間に応じて、生成される時間と比較して十分です。新しい行が処理できる速度より速く生成された場合、このアプローチはうまくいかず、スタックが大きくなりすぎてメモリ不足になります。その場合、要件に応じて、古いエントリを破棄するサイズ制限付きスタックを手に入れることができます。

1

つのアイデア:

  1. ではなく、CSVの固定サイズレコード形式を使用します。その後、改行を探すのではなく、あなたのレコードがどんなオフセットであるかを正確に知ることができます。

  2. これが不可能な場合は、ファイルから項目を読み込んでスタックにプッシュするスレッドを用意してください。別のスレッドは、スタックからアイテムをポップし、それらを処理します。スタックなので、常に最新のアイテムを扱うことになります。スタックが大きすぎる場合にどのように対処したいのかを理解する必要があります。あまりにも古すぎるアイテムを捨てたいだけですか?

0

元のスクリプトにアクセスできる場合は、CSVファイルに加えてデータベースにレコードを書き込みます。それで、データベースで何でもできます。最後のレコードにアクセスしたり、レポートを実行したりすることができます。

0

この結果、不要なスキャン操作が発生します。

私はある時点を探して、次の有効なCSV行の開始位置を見つけて、次の改行が来るまで読んでいると仮定します。

私はあなたが現在何をしているかよりも効率的な場合があり、これを行うには3つの方法を考えることができ

  1. は、ファイル全体を読み、前方方向に列を解析、メモリ内の位置を保存します。その後、メモリ内の行を逆の順序で処理します。

  2. 行の開始を探してファイルを最初からスキャンし、行の開始位置をメモリに格納します。次に逆の順序で位置を反復し、それぞれに対応する行を読み込ませます。 (各シークで複数の行を処理することで、より効率的に入力を行うことができます。)

  3. MappedByteBufferを使用してファイルをメモリにマップすると、Byteバッファを順方向または逆方向にステップ実行して行境界を見つけることができます。

最初のアプローチでは、メモリ内のファイル全体をバッファリングすることができている必要がありますが、システムコールの最小数と一度だけファイルを読み込むので、下のI/Oのオーバーヘッドを持っています。 3番目のアプローチは同じ問題を抱えていますが、非常に大きなファイルを(大)セクションのメモリにマップしてメモリ要件を減らすこともできます。

しかし最終的には、Javaでファイルを後方に読む単純かつ効率的な方法はありません。

0

アプリケーションはUnix環境で実行されている場合は、カスタム・プログラムは、単に標準入力を受け入れ、Javaプログラムとのソケット接続にそれをエコーう

tail -f /csv-file | custom-program 

を実行することができます。

あなたのJavaプログラムは、そのようなコマンドラインから起動できない何らかのサーバーアプリケーションであると仮定しています。もしそれが実際に大丈夫なら、Javaプログラムでcustom-programを置き換えることができます。