1

私は 2 つの Java プロセスを持っていProcessorますSimulator。は、5 秒ごとに所定のデータ レコード (10 行のテキスト) にSimulator書き込みます。File XProcessorこのファイルを継続的に読み取り、トークンが有効なレコードを示すのを待ちます。コードは次のとおりです (ファイル名をいくつか置き換えています)。

ではSimulator、5 秒ごと:

FileWriter fileWriter = new FileWriter(DATA_FILE, true);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write(DATA);
bufferedWriter.close();

ではProcessor、常に:

mScanner = new Scanner(new BufferedReader(
        new FileReader(DATA_FILE)));
mScanner.useLocale(Locale.UK);

while (true) {              
    while (mScanner.hasNextLine()) {
    // Parse the data bundle.
    if (parseDataBundle()) {
            ...
        }
    }
}

以前は、Processorが にフックされていて、 (適切に構成された) を使用して到着したデータを読み取ることにInputStream問題はありませんでした。Scanner

ここでは、メモ帳でファイルを更新して生成されたときに、データが正しく書き込まれていることがわかります。しかし、InputStream ではなくファイルを使用すると、if ( parseDataBundle()) {行に到達することはありません。

私は何を間違っていますか?Processor実行中は削除できないため、ファイルリソースを保持しているようです。私の腸は、おそらく並行性の誤用と関係があると考えています。

4

2 に答える 2

2

ファイルの悪用だと思います。ファイルはメッセージング用に設計されたものではありません。ファイルの終わりに到達したら、それで終わりです。これを回避する唯一の方法は、(長さをチェックして) より多くのデータがあることがわかっている場合にのみ読み取るようにすることです。テキストを使用する場合、これはより複雑になります。

テキスト付きのファイルを使用できますが、扱いにくいです。1 つのスレッドでファイル サイズをポーリングする必要があり、サイズが変更された場合は、追加されたバイトだけを読み取ります (それ以上は読み取りません)。これはパイプに書き込むことができます。読み取りスレッドは、InputStreamReader と BufferedReader を使用してパイプから読み取ることができます。


ポーリング間隔を変更するには、次のようなエスカレートするスリープ間隔を使用できます

long lastSize = 
int maxSleep = 5000, sleep = 200;
while(!Thread.currentThread().isInterrupted()) {
     long size = file.length();
     if (size > lastSize) {
        copyData(size - lastSize);
        lastSize = size;
        sleep = 200;
     } else {
        Thread.sleep(sleep);
        sleep += 200;
        if (sleep > maxSleep)
            sleep = maxSleep;
}

このアプローチの利点は、メッセージを取得する速度に合わせてスリープする時間が調整されることです。

于 2013-07-19T12:14:28.267 に答える
0

Java NIO は、ファイル ロックのサポートを提供します。基盤となる OS に応じて、書き込み中にファイルの排他ロックを取得し、書き込みが完了した後にロックを解放できます。別のプロセスがロックを取得しようとする可能性があります。ロックが取得された場合は、ファイルを読み取って解放します。ロックを取得するまでポーリングします。アイデアが得られることを願っています。FileChannel#lock() APIを見てください。

于 2013-07-19T13:04:04.163 に答える