Java 目錄事件

2018-02-05 11:45 更新

Java IO教程 - Java目錄事件


當文件系統(tǒng)中的對象被修改時,我們可以監(jiān)聽watch服務以獲取警報。

java.nio.file包中的以下類和接口提供watch服務。

  • Watchable接口
  • WatchService接口
  • WatchKey接口
  • WatchEvent接口
  • WatchEvent.Kind接口
  • StandardWatchEventKinds類

可監(jiān)視對象表示可以被監(jiān)視的文件系統(tǒng)對象??捎^看對象可以向手表服務注冊。

Path對象是一個Watchable對象。

WatchService表示觀察服務。當一個對象使用WatchService注冊時,WatchService返回一個WatchKey作為注冊的令牌。

WatchEvent表示注冊到監(jiān)視服務的對象上的事件。它的kind()方法返回發(fā)生的事件的類型。

它的context()方法返回一個Path對象,它表示事件發(fā)生的條目。

count()方法返回特定通知的事件發(fā)生次數(shù)。 如果它返回大于1的值,那么它是一個重復的事件。

WatchEvent.Kind <T>表示發(fā)生的事件的類型。

StandardWatchEventKinds類定義了用于表示事件種類的常量,如下所示。

  • ENTRY_CREATE
  • ENTRY_DELETE
  • ENTRY_MODIFY
  • OVERFLOW

OVERFLOW表示丟失或丟棄的事件。

創(chuàng)建觀察服務以觀察目錄以進行更改。

WatchService ws = FileSystems.getDefault().newWatchService();

要使用Watch服務注冊目錄,使用register()方法,該方法將返回一個WatchKey對象作為注冊令牌。

// Get  a  Path  object for C:\myName  directory  to watch
Path  dirToWatch  = Paths.get("C:\\myName");
WatchKey token   = dirToWatch.register(ws, ENTRY_CREATE,  ENTRY_MODIFY,  ENTRY_DELETE);

要取消注冊,請使用WatchKey的cancel()方法。

當注冊目錄時,其WatchKey處于就緒狀態(tài)。

我們可以通過手表服務注冊多個目錄。

要從監(jiān)視服務隊列中檢索WatchKey,使用WatchService對象的take()或poll()方法來檢索和刪除發(fā)出信號并排隊的WatchKey。

take()方法等待,直到WatchKey可用。poll()方法允許我們?yōu)榈却付ǔ瑫r。

以下代碼使用無限循環(huán)來檢索發(fā)出信號的WatchKey。

while(true)  {
    WatchKey key  = ws.take();
}

處理事件

WatchKey的pollEvents()方法檢索并刪除所有掛起的事件。它返回一個WatchEvent的列表。 List的每個元素代表WatchKey上的一個事件。

以下代碼顯示了處理事件的典型邏輯:

while(true)  {
    WatchKey key  = ws.take();
    // Process all  events of  the   WatchKey 
    for(WatchEvent<?> event  : key.pollEvents())  {
       // Process each  event here
    }
}

處理事件后重置WatchKey

我們需要重置WatchKey對象,通過調用其reset()方法來再次接收事件通知。

reset()方法將WatchKey置于就緒狀態(tài)。如果WatchKey仍然有效,reset()方法返回true。 否則,它返回false。

如果WatchKey被取消或其監(jiān)視服務關閉,它可能會失效。

// Reset   the   WatchKey
boolean isKeyValid = key.reset();
if (!isKeyValid)  {
    System.out.println("No  longer  watching "  + dirToWatch);
}

WatchService是可自動關閉的。我們可以在try-with-resources中創(chuàng)建一個WatchService的對象塊,當程序退出塊時它將自動關閉。

例子

以下代碼顯示了如何實現(xiàn)監(jiān)視服務以監(jiān)視目錄中的更改。

import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
import static java.nio.file.StandardWatchEventKinds.OVERFLOW;

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.WatchEvent;
import java.nio.file.WatchEvent.Kind;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;

public class Main {
  public static void main(String[] args) {
    try (WatchService ws = FileSystems.getDefault().newWatchService()) {
      Path dirToWatch = Paths.get("C:\\myName");
      dirToWatch.register(ws, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE);
      while (true) {
        WatchKey key = ws.take();
        for (WatchEvent<?> event : key.pollEvents()) {
          Kind<?> eventKind = event.kind();
          if (eventKind == OVERFLOW) {
            System.out.println("Event  overflow occurred");
            continue;
          }
          WatchEvent<Path> currEvent = (WatchEvent<Path>) event;
          Path dirEntry = currEvent.context();
          System.out.println(eventKind + "  occurred on  " + dirEntry);
        }
        boolean isKeyValid = key.reset();
        if (!isKeyValid) {
          System.out.println("No  longer  watching " + dirToWatch);
          break;
        }
      }
    } catch (IOException | InterruptedException e) {
      e.printStackTrace();
    }
  }
}
以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號