Ответ 1
Когда запись будет создана, вы получите событие ENTRY_CREATE
. Для каждой последующей модификации вы получите ENTRY_MODIFY
событие. Когда копирование завершено, вы будете уведомлены с помощью ENTRY_MODIFY
.
Я использую WatchService API для просмотра каталога и получения ENTRY_CREATE события, когда пользователь начинает копировать файл в каталог. Файлы, с которыми я работаю, могут быть большими, и я хотел бы знать, когда копия будет закончена. Есть ли встроенный java API, который я могу использовать для этого, или мне лучше всего отслеживать размер созданных файлов и начать обработку, когда размер перестает расти?
EDIT: Вот мой пример кода:
package com.example;
import java.io.File;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
public class Monitor {
public static void main(String[] args) {
try {
String path = args[0];
System.out.println(String.format( "Monitoring %s", path ));
WatchService watcher = FileSystems.getDefault().newWatchService();
Path watchPath = FileSystems.getDefault().getPath(path);
watchPath.register(watcher, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_MODIFY);
while (true) {
WatchKey key = watcher.take();
for (WatchEvent<?> event: key.pollEvents()) {
Object context = event.context();
System.out.println( String.format( "Event %s, type %s", context, event.kind() ));
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Что выдает этот вывод:
Monitoring /Users/ericcobb/Develop/watch
Event .DS_Store, type ENTRY_MODIFY
Event 7795dab5-71b1-4b78-952f-7e15a2f39801-84f3e5daeca9435aa886fbebf7f8bd61_4.mp4, type ENTRY_CREATE
Когда запись будет создана, вы получите событие ENTRY_CREATE
. Для каждой последующей модификации вы получите ENTRY_MODIFY
событие. Когда копирование завершено, вы будете уведомлены с помощью ENTRY_MODIFY
.
Однако оба этих решения должны быть реализованы в приложении для написания. Я думаю, вы не можете точно сказать из приложения для чтения.
Это библиотека, которую мы используем сегодня:
https://github.com/levelsbeyond/jpoller
Это вилка проекта с открытым исходным кодом, которого автор уже не поддерживает. Мы исправили несколько ошибок, и сегодня используем его в производстве.
Он работает, проверяя размер файлов в каталоге и рассматривает сделанный файл (готовый к обработке) после того, как размер файла перестает расти в течение определенного периода времени.
Возможно, вы можете сказать, пытаясь получить доступ на запись к файлу, но это зависит от двух факторов и требует исследований:
File file = child.toAbsolutePath().toFile();
if(file.isFile() && file.isWrite())
{
}
Возможно, это будет способ узнать, чего вы хотите, но не в инструкции while.
Он будет работать, когда вы действительно получите доступ к файлу.
Единственный допустимый вариант, чтобы гарантировать, что никакой другой процесс не записывает в файл больше, - это успешно получить блокировку записи в файле. Хотя немного неуклюжий, вы можете использовать FileChannel и FileLock для этой цели
try(FileChannel ch = FileChannel.open(p, StandardOpenOption.WRITE);
FileLock lock = ch.tryLock()){
if(lock == null) {
//no lock, other process is still writing
} else {
//you got a lock, other process is done writing
}
} catch (IOException e) {
//something else went wrong
}
Вы также можете получить блокировку с помощью ch.lock()
, который является блокирующим вызовом. Но поскольку события ENTRY_MODIFY непрерывно генерируются при записи файла, вы также можете использовать tryLock и ждать следующего события.