|
Spec-Zone .ru
спецификации, руководства, описания, API
|
Вы когда-либо редактировали файл, используя IDE или другого редактора, и диалоговое окно, кажется, сообщает Вам, что один из открытых файлов изменился на файловой системе и должен быть перезагружен? Или возможно, как IDE NetBeans, приложение только спокойно обновляет файл, не уведомляя Вас. Следующее демонстрационное диалоговое окно показывает, как это уведомление смотрит со свободным редактором, jEdit:

Чтобы реализовать эту функциональность, названную уведомлением об изменении файла, программа должна быть в состоянии обнаружить то, что происходит с соответствующим каталогом на файловой системе. Один способ сделать так состоит в том, чтобы опросить файловую систему, ища изменения, но этот подход неэффективен. Это не масштабируется к приложениям, у которых есть сотни открытых файлов или каталогов, чтобы контролировать.
java.nio.file пакет обеспечивает API уведомления об изменении файла, названный API Службы Часов. Этот API позволяет Вам зарегистрировать каталог (или каталоги) со службой часов. Регистрируясь, Вы говорите службу, какими типами событий Вы интересуетесь: создание файла, удаление файла, или модификация файла. Когда служба обнаруживает мероприятие, она передается зарегистрированному процессу. У зарегистрированного процесса есть поток (или пул потоков) выделенный наблюдению за любыми событиями, для которых это зарегистрировалось. Когда событие входит, оно обрабатывается как необходимый.
Этот раздел покрывает следующее:
WatchService API является довольно низким уровнем, разрешая Вам настроить это. Можно использовать это как есть, или можно хотеть создавать высокоуровневый API сверху этого механизма так, чтобы это подошло для Ваших определенных потребностей.
Вот основные шаги, требуемые реализовывать службу часов:
WatchService "наблюдатель" для файловой системы.WatchKey экземпляр для каждого каталога, который Вы регистрируете.closed метод).WatchKeys ориентированы на многопотоковое исполнение и может использоваться с java.nio.concurrent пакет. Можно выделить
Поскольку этот API более совершенствуется, испытайте его перед продолжением. Сохраните пример к Вашему компьютеру, и компиляция это. Создайте a WatchDirtest каталог, который передадут к примеру. WatchDir использует единственный поток, чтобы обработать все события, таким образом, он блокирует ввод с клавиатуры, ожидая событий. Или выполните программу в отдельном окне, или в фоновом режиме, следующим образом:
java WatchDir test &
Игра с созданием, удалением, и редактированием файлов в test каталог. Когда любое из этих событий имеет место, сообщение печатается к консоли. Когда Вы закончили, удалите test каталог и WatchDir выходы. Или, если Вы предпочитаете, можно вручную уничтожить процесс.
Можно также наблюдать все дерево файла, определяя -r опция. Когда Вы определяете -r, WatchDir
обходит дерево файла, регистрируя каждый каталог в службе часов.
Первый шаг должен создать новое WatchService при использовании метод в FileSystem class, следующим образом:
WatchService watcher = FileSystems.getDefault().newWatchService();
Затем, зарегистрируйте один или более объектов в службе часов. Любой объект, который реализует интерфейс может быть зарегистрирован. Path class реализует Watchable интерфейс, таким образом, каждый каталог, который будет контролироваться, регистрируется как a Path объект.
Как с любым Watchable, Path class реализует два register методы. Эта страница использует версию с двумя параметрами, . (Версия с тремя параметрами берет a WatchEvent.Modifier, который в настоящий момент не реализуется.)
Регистрируя объект в службе часов, Вы определяете типы событий, которых Вы хотите следить за развитием. Поддерживаемый типы события следуют:
ENTRY_CREATE – Запись в каталоге создается.ENTRY_DELETE – Запись в каталоге удаляется.ENTRY_MODIFY – Запись в каталоге изменяется.OVERFLOW – Указывает, что события, возможно, были потеряны или отброшены. Вы не должны зарегистрироваться для OVERFLOW событие, чтобы получить это.Следующий фрагмент кода показывает, как зарегистрировать a Path экземпляр для всех трех типов события:
import static java.nio.file.StandardWatchEventKinds.*;
Path dir = ...;
try {
WatchKey key = dir.register(watcher,
ENTRY_CREATE,
ENTRY_DELETE,
ENTRY_MODIFY);
} catch (IOException x) {
System.err.println(x);
}
Порядок событий в цикле обработки событий следует:
null значение, если недоступный.TimeUnit параметр определяет, является ли требуемое время наносекундами, миллисекундами, или некоторой другой единицей времени.List из от метод.OVERFLOW событие. Можно хотеть обрабатывать переполнение или игнорировать его, но следует протестировать на него.ready состояние, вызывая . Если этот метод возвращается false, ключ больше не действителен, и цикл может выйти. Этот шаг очень важен. Если Вы не в состоянии вызвать reset, этот ключ не будет получать дальнейшие события.У ключа часов есть состояние. В любой момент времени его состояние могло бы быть одним из следующего:
Ready указывает, что ключ готов принять события. Когда сначала создающийся, ключ находится в состоянии готовности.Signaled указывает, что одно или более событий ставятся в очередь. Как только ключ был сообщен, это больше не находится в состоянии готовности до метод вызывается.Invalid указывает, что ключ больше не является активным. Это состояние происходит, когда одно из следующих событий имеет место: Вот пример цикла обработки событий. Это берется от метод. Намерение - это text/plain файлы будут посланы по электронной почте к псевдониму, но ту деталь реализации оставляют читателю.
Методы, определенные для API службы часов, показывают полужирным:
for (;;) {
// wait for key to be signaled
WatchKey key;
try {
key = watcher.take();
} catch (InterruptedException x) {
return;
}
for (WatchEvent<?> event: key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
// This key is registered only
// for ENTRY_CREATE events,
// but an OVERFLOW event can
// occur regardless if events
// are lost or discarded.
if (kind == OVERFLOW) {
continue;
}
// The filename is the
// context of the event.
WatchEvent<Path> ev = (WatchEvent<Path>)event;
Path filename = ev.context();
// Verify that the new
// file is a text file.
try {
// Resolve the filename against the directory.
// If the filename is "test" and the directory is "foo",
// the resolved name is "test/foo".
Path child = dir.resolve(filename);
if (!Files.probeContentType(child).equals("text/plain")) {
System.err.format("New file '%s'" +
" is not a plain text file.%n", filename);
continue;
}
} catch (IOException x) {
System.err.println(x);
continue;
}
// Email the file to the
// specified email alias.
System.out.format("Emailing file %s%n", filename);
//Details left to reader....
}
// Reset the key -- this step is critical if you want to
// receive further watch events. If the key is no longer valid,
// the directory is inaccessible so exit the loop.
boolean valid = key.reset();
if (!valid) {
break;
}
}
Имя файла получается от контекста события.
WatchEvent<Path> ev = (WatchEvent<Path>)event; Path filename = ev.context();
Когда Вы компилируете Email пример, это генерирует следующую ошибку:
Note: Email.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details.
Эта ошибка является результатом строки кода, который бросает WatchEvent<T> к a WatchEvent<Path>. пример избегает этой ошибки, создавая утилиту WatchDircast метод, который подавляет предупреждение непроверенное, следующим образом:
@SuppressWarnings("unchecked")
static <T> WatchEvent<T> cast(WatchEvent<?> event) {
return (WatchEvent<Path>)event;
}
Если Вы незнакомы с @SuppressWarnings синтаксис, см. Аннотации.
API Службы Часов разрабатывается для приложений, которые должны быть уведомлены о событиях изменения файла. Это хорошо подходит для любого приложения, как редактор или IDE, который потенциально имеет много открытых файлов и должен гарантировать, что файлы синхронизируются с файловой системой. Это также хорошо подходит для сервера приложений, который наблюдает каталог, возможно ожидающий .jsp или .jar файлы, чтобы отбросить, чтобы развернуть их.
Этот API не разрабатывается для того, чтобы индексировать жесткий диск. У большинства реализаций файловой системы есть собственная поддержка уведомления об изменении файла. API Службы Часов использует в своих интересах эту поддержку где доступный. Однако, когда файловая система не поддерживает этот механизм, Служба Часов опросит файловую систему, ожидающую событий.