Как дождаться окончания процесса Windows, прежде чем открывать файл в Java - PullRequest
4 голосов
/ 01 декабря 2011

У меня есть встроенный слушатель, который уведомляет, если мы получаем новый файл в определенном каталоге. Это реализуется путем опроса и использования TimerTask. Теперь программа настроена так, что, получив новый файл, она вызывает другую Java-программу, которая открывает файл и проверяет, является ли он правильным файлом. Моя проблема в том, что, поскольку опрос происходит через указанное количество секунд, может возникнуть ситуация, когда файл копируется в этот каталог и, следовательно, блокируется окнами.

Это вызывает исключение IOException, поскольку другая Java-программа, которая пытается открыть его для проверки, не может («Файл используется другим процессом»).

Есть ли способ узнать, когда Windows закончила копирование, а затем вызвать вторую программу для проверки из Java?

Я буду очень рад опубликовать фрагменты кода, если они кому-то понадобятся, чтобы помочь.

Спасибо

Ответы [ 3 ]

4 голосов
/ 21 марта 2013

Большое спасибо за помощь, у меня была такая же проблема с WatchEvent. К сожалению, как вы сказали, file.canRead () и file.canWrite () оба возвращают true, даже если файл все еще заблокирован Windows. Итак, я обнаружил, что если я пытаюсь «переименовать» его с тем же именем, я знаю, работает ли Windows на нем или нет. Вот что я сделал:

    while(!sourceFile.renameTo(sourceFile)) {
        // Cannot read from file, windows still working on it.
        Thread.sleep(10);
    }
3 голосов
/ 01 декабря 2011

Это немного сложно.Было бы легко, если бы вы могли контролировать или, по крайней мере, общаться с программой, копирующей файл, но это не будет возможно с Windows, я думаю.Некоторое время назад мне приходилось сталкиваться с подобной проблемой с программным обеспечением SFU , и я решил ее, пытаясь открыть файл для записи, пока он не станет доступным.

Чтобы избежать высокой загрузки ЦП при цикле, проверка файла может быть выполнена с экспоненциальным распределением скорость.

РЕДАКТИРОВАТЬ Возможное решение:

File fileToCopy = File(String pathname);
int sleepTime = 1000; // Sleep 1 second
while(!fileToCopy .canWrite()){
    // Cannot write to file, windows still working on it
    Sleep(sleepTime);
    sleepTime *= 2; // Multiply sleep time by 2 (not really exponential but will do the trick)
    if(sleepTime > 30000){ 
        // Set a maximum sleep time to ensure we are not sleeping forever :)
        sleepTime = 30000;
    }
}
// Here, we have access to the file, go process it
processFile(fileToCopy);
0 голосов
/ 01 декабря 2011

Я думаю, что вы можете создать объект File и затем использовать canRead или canWrite, чтобы узнать, готов ли файл для использования другой Java-программой.

http://docs.oracle.com/javase/6/docs/api/java/io/File.html

Другой вариант - попытаться открыть файл в первой программе и, если он выдает исключение, не вызывать другую Java-программу. Но я рекомендую выше 'File вариант.

...