Skip to content

Commit

Permalink
feat(file-io): 🎸 watch service, translated
Browse files Browse the repository at this point in the history
Refers: #9
  • Loading branch information
rcmoutinho committed Sep 13, 2019
1 parent b74123d commit 492aee3
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 91 deletions.
110 changes: 55 additions & 55 deletions book/07-file-io/sections/05-watch-service.asc
Original file line number Diff line number Diff line change
Expand Up @@ -3,134 +3,134 @@

=== WatchService

.Objetivo
.Objective
--------------------------------------------------
Observe the changes in a directory by using the WatchService interface
-
Observar as mudanças em um diretório a partir da utilização da Interface WatchService
--------------------------------------------------

O WatchService é uma API para monitorar mudanças em arquivos e diretórios. Serão apresentadas as principais formas de realizar essa monitoração.
WatchService is an API for monitoring file and directory changes. The main ways to carry out this monitoring will be presented.

Para utilizar a API são necessárias 4 classes principais:
To use the API you need 4 main classes:

* WatchService -> representa o serviço em si de monitoração;
* StandardWatchEventKinds -> representa os tipos de alteração que se deseja monitorar: criar, apagar ou modificar;
* WatchKey -> representa um retorno do serviço informando que houveram alterações;
* WatchEvent -> representa um evento em si, onde é possível obter informações do que foi alterado.
* WatchService -> represents the monitoring service itself;
* StandardWatchEventKinds -> represents the types of changes you want to monitor: create, delete or modify;
* WatchKey -> represents a return of the service informing that there have been changes;
* WatchEvent -> represents an event itself, where you can get information about what has changed.

//-
// -

. É possível observar criações ou deleções de arquivos em um diretório.
. You can observe file creations or deletions in a directory.
+
[source,java,indent=0]
.{java-package}/watchservice/WatchService_CreateDelete.java
----
include::{section-java-package}/watchservice/WatchService_CreateDelete.java[tag=code]
----
+
.Saída no console
.console output
[source,console]
----
Path: /home/rinaldo/arquivos
Eventos capturados. Quantidade: 1
Evento ocorrido. Tipo : ENTRY_DELETE. Contexto: arquivo1.txt
Eventos capturados. Quantidade: 1
Evento ocorrido. Tipo : ENTRY_CREATE. Contexto: arquivo1.txt
Path: /home/rinaldo/files
Events captured. Quantity: 1
Event occurred. Type: ENTRY_DELETE. Context: file1.txt
Events captured. Quantity: 1
Event occurred. Type: ENTRY_CREATE. Context: file1.txt
----
+
Isso é o que seria impresso no console caso o `arquivo1.txt` fosse apagado e depois criado novamente.
This is what would be printed on the console if `file1.txt` were deleted and then created again.
+
Perceba os passos que foram feitos:
Note the steps that were taken:
+
.. Um WatchService foi criado
.. O service foi registrado no `Path` com os eventos desejados
.. Foi criado um _loop_ infinito para realizar a monitoração de forma contínua
.. Foi chamado o método `take`, que aguarda até haver eventos e assim, retorná-los
.. Foi chamado o método `pollEvents` para recuperar os eventos que ocorreram
.. Os eventos foram impressos no console
.. O `WatchKey` foi resetado para que pudesse ser utilizado novamente
.. A WatchService has been created.
.. The service has been registered in `Path` with the desired events.
.. An infinite _loop_ has been created to continuously monitor.
.. The `take` method was called, which waits until there are events and thus returns them.
.. The `pollEvents` method was called to retrieve events that occurred.
.. Events were printed on console.
.. WatchKey has been reset so that it can be used again.

+
Esse é o básico de um `WatchService`. Perceba que ele é um recurso que deve ser fechado, por isso está na sintaxe de `try-with-resources`.
This is the basics of a `WatchService`. Note that it is a resource that must be closed, so it is in the `try-with-resources` syntax.

. É possível monitorar mudanças em arquivos de um diretório.
. You can monitor changes to files in a directory.
+
[source,java,indent=0]
.{java-package}/watchservice/WatchService_Modify.java
----
include::{section-java-package}/watchservice/WatchService_Modify.java[tag=code]
----
+
.Saída no console
.console output
[source,console]
----
Path: /home/rinaldo/arquivos
Eventos capturados. Quantidade: 1
Evento ocorrido. Tipo : ENTRY_MODIFY. Contexto: .arquivo1.txt.kate-swp
Eventos capturados. Quantidade: 1
Evento ocorrido. Tipo : ENTRY_MODIFY. Contexto: arquivo1.txt.h26197
Eventos capturados. Quantidade: 1
Evento ocorrido. Tipo : ENTRY_MODIFY. Contexto: arquivo1.txt.h26197
Path: /home/rinaldo/files
Events captured. Quantity: 1
Event occurred. Type: ENTRY_MODIFY. Context: .file1.txt.kate-swp
Events captured. Quantity: 1
Event occurred. Type: ENTRY_MODIFY. Context: file1.txt.h26197
Events captured. Quantity: 1
Event occurred. Type: ENTRY_MODIFY. Context: file1.txt.h26197
----
+
Esses foram os eventos que ocorreram ao abrir o `arquivo1.txt` com o editor `Kate`, acrescentar um caracter, e salvar o arquivo.
These were the events that occurred when opening `file1.txt` with the `Kate` editor, adding a character, and saving the file.

. Não é possível monitorar diretamente um arquivo.
. Unable to monitor a file directly.
+
[source,java,indent=0]
.{java-package}/watchservice/WatchService_File.java
----
include::{section-java-package}/watchservice/WatchService_File.java[tag=code]
----
+
.Saída no console
.console output
[source,console]
----
Path: /home/rinaldo/arquivos/arquivo1.txt
java.nio.file.NotDirectoryException: /home/rinaldo/arquivos/arquivo1.txt
Path: /home/rinaldo/files/file1.txt
java.nio.file.NotDirectoryException: /home/rinaldo/files/file1.txt
at sun.nio.fs.LinuxWatchService$Poller.implRegister(LinuxWatchService.java:249)
at sun.nio.fs.AbstractPoller.processRequests(AbstractPoller.java:260)
at sun.nio.fs.LinuxWatchService$Poller.run(LinuxWatchService.java:364)
at java.lang.Thread.run(Thread.java:748)
----
+
Perceba que ocorre exceção ao tentar monitorar diretamente o `arquivo1.txt`.
Note that exception occurs when trying to directly monitor `file1.txt`.

. É possível recuperar um `WatchKey` imediatamente ou aguardar um período específico com os métodos `poll`.
. You can retrieve a `WatchKey` immediately or wait for a specific period with `poll` methods.
+
[source,java,indent=0]
.{java-package}/watchservice/WatchService_Poll.java
----
include::{section-java-package}/watchservice/WatchService_Poll.java[tag=code]
----
+
.Saída no console
.console output
[source,console]
----
Path: /home/rinaldo/arquivos
Horário antes do poll sem timeout: 14:55:10.298
WatchKey do poll: null
Horário depois do poll sem timeout: 14:55:10.298
Horário antes do poll com timeout: 14:55:10.298
WatchKey do poll com timeout: null
Horário depois do poll com timeout: 14:55:15.300
Path: /home/rinaldo/files
Time before poll without timeout: 14:55:10.298
WatchKey's poll: null
Time after poll without timeout: 14:55:10.298
Time before poll with timeout: 14:55:10.298
WatchKey's poll with timeout: null
Time after poll with timeout: 14:55:15.300
----
+
Perceba que o primeiro `poll` retorna imediatamente, mesmo que nenhum evento tenha ocorrido. Já o segundo aguarda por 5 segundos para retornar, mesmo que não haja evento.
Note that the first `poll` returns immediately, even if no events have occurred. The second waits for 5 seconds to return, even if there is no event.
+
Nos cenários de monitoração, o ideal é utilizar o `take`, caso contrário seria necessário invocar o `poll` inúmeras vezes, enquanto o `take` apenas aguarda indefinidamente até que haja um evento.
In monitoring scenarios, it is best to use take, otherwise you would need to invoke poll countless times, while take only waits indefinitely until there is an event.


.References
****
* Monitoring a Directory for Changes
+
Boyarsky, Jeanne; Selikoff, Scott. OCP: Oracle Certified Professional Java SE 8 Programmer II Study Guide (p. 625). Wiley. Edição do Kindle.
Boyarsky, Jeanne; Selikoff, Scott. OCP: Oracle Certified Professional Java SE 8 Programmer II Study Guide (p. 625). Wiley. Kindle Edition.
* https://www.baeldung.com/java-nio2-watchservice[A Guide to WatchService in Java NIO2.]
* https://docs.oracle.com/javase/7/docs/api/java/nio/file/WatchService.html[Class Files.] Java Plataform SE 7.
* https://docs.oracle.com/javase/tutorial/essential/io/notification.html[Watching a Directory for Changes.] The Java™ Tutorials.
****
****
24 changes: 12 additions & 12 deletions src/org/j6toj8/fileio/watchservice/WatchService_CreateDelete.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,25 @@ public class WatchService_CreateDelete {
public static void main(String[] args) {
// tag::code[]
String userHome = System.getProperty("user.home");
Path path = Paths.get(userHome, "arquivos");
Path path = Paths.get(userHome, "files");
System.out.println("Path: " + path);

// criação do WatchService - ainda sem monitorar nada
// WatchService creation - still not monitoring anything
try (WatchService service = FileSystems.getDefault().newWatchService();) {
// registro do WatchService no Path para monitorar os evento de CREATE e DELETE

// WatchService log in Path to monitor CREATE and DELETE events
path.register(service, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE);

while (true) { // loop infinito
// take() irá retornar sempre que houverem eventos
// caso contrário a chamada fica parada esperando eventos ocorrerem
while (true) { // infinite loop
// take() will return whenever there are events
// otherwise the call is stopped waiting for events to occur
WatchKey key = service.take();
List<WatchEvent<?>> pollEvents = key.pollEvents(); // recupera os eventos ocorridos
System.out.println("Eventos capturados. Quantidade: " + pollEvents.size());
for (WatchEvent<?> event : pollEvents) { // iteração sobre todos os eventos recuperados
System.out.println("Evento ocorrido. Tipo : " + event.kind() + ". Contexto: " + event.context());
List<WatchEvent<?>> pollEvents = key.pollEvents(); // recovers events
System.out.println("Events captured. Quantity: " + pollEvents.size());
for (WatchEvent<?> event : pollEvents) { // iteration over all retrieved events
System.out.println("Event occurred. Type: " + event.kind() + ". Context: " + event.context());
}
key.reset(); // reseta o WatchKey para que possa ser utilizado novamente
key.reset(); // resets WatchKey so that it can be used again
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
Expand Down
4 changes: 2 additions & 2 deletions src/org/j6toj8/fileio/watchservice/WatchService_File.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ public class WatchService_File {
public static void main(String[] args) {
// tag::code[]
String userHome = System.getProperty("user.home");
Path path = Paths.get(userHome, "arquivos", "arquivo1.txt"); // NÃO SUPORTADO
Path path = Paths.get(userHome, "files", "file1.txt"); // NOT SUPPORTED
System.out.println("Path: " + path);

try (WatchService service = FileSystems.getDefault().newWatchService();) {
path.register(service, StandardWatchEventKinds.ENTRY_MODIFY); // LANÇA EXCEÇÃO
path.register(service, StandardWatchEventKinds.ENTRY_MODIFY); // THROWS EXCEPTION
} catch (IOException e) {
e.printStackTrace();
}
Expand Down
26 changes: 13 additions & 13 deletions src/org/j6toj8/fileio/watchservice/WatchService_Modify.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,25 @@ public class WatchService_Modify {
public static void main(String[] args) {
// tag::code[]
String userHome = System.getProperty("user.home");
Path path = Paths.get(userHome, "arquivos");
Path path = Paths.get(userHome, "files");
System.out.println("Path: " + path);

// criação do WatchService - ainda sem monitorar nada
// WatchService creation - still not monitoring anything
try (WatchService service = FileSystems.getDefault().newWatchService();) {
// registro do WatchService no Path para monitorar o evento de MODIFY

// WatchService log in Path to monitor MODIFY event
path.register(service, StandardWatchEventKinds.ENTRY_MODIFY);
while (true) { // loop infinito
// take() irá retornar sempre que houverem eventos
// caso contrário a chamada fica parada esperando eventos ocorrerem

while (true) { // infinite loop
// take() will return whenever there are events
// otherwise the call is stopped waiting for events to occur
WatchKey key = service.take();
List<WatchEvent<?>> pollEvents = key.pollEvents(); // recupera os eventos ocorridos
System.out.println("Eventos capturados. Quantidade: " + pollEvents.size());
for (WatchEvent<?> event : pollEvents) { // iteração sobre todos os eventos recuperados
System.out.println("Evento ocorrido. Tipo : " + event.kind() + ". Contexto: " + event.context());
List<WatchEvent<?>> pollEvents = key.pollEvents(); // recovers events
System.out.println("Events captured. Quantity: " + pollEvents.size());
for (WatchEvent<?> event : pollEvents) { // iteration over all retrieved events
System.out.println("Event occurred. Type: " + event.kind() + ". Context: " + event.context());
}
key.reset(); // reseta o WatchKey para que possa ser utilizado novamente
key.reset(); // resets WatchKey so that it can be used again
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
Expand Down
18 changes: 9 additions & 9 deletions src/org/j6toj8/fileio/watchservice/WatchService_Poll.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,21 @@ public class WatchService_Poll {
public static void main(String[] args) {
// tag::code[]
String userHome = System.getProperty("user.home");
Path path = Paths.get(userHome, "arquivos");
Path path = Paths.get(userHome, "files");
System.out.println("Path: " + path);

try (WatchService service = FileSystems.getDefault().newWatchService();) {
path.register(service, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE);

System.out.println("Horário antes do poll sem timeout: " + LocalTime.now());
WatchKey key1 = service.poll(); // retorna imediatamente, mesmo que não haja evento
System.out.println("WatchKey do poll: " + key1);
System.out.println("Horário depois do poll sem timeout: " + LocalTime.now());
System.out.println("Time before poll without timeout: " + LocalTime.now());
WatchKey key1 = service.poll(); // returns immediately even if there is no event
System.out.println("WatchKey's poll: " + key1);
System.out.println("Time after poll without timeout: " + LocalTime.now());

System.out.println("Horário antes do poll com timeout: " + LocalTime.now());
WatchKey key2 = service.poll(5, TimeUnit.SECONDS); // retorna após 5 segundos, mesmo que não haja evento
System.out.println("WatchKey do poll com timeout: " + key2);
System.out.println("Horário depois do poll com timeout: " + LocalTime.now());
System.out.println("Time before poll with timeout: " + LocalTime.now());
WatchKey key2 = service.poll(5, TimeUnit.SECONDS); // returns after 5 seconds even if there is no event
System.out.println("WatchKey's poll with timeout: " + key2);
System.out.println("Time after poll with timeout: " + LocalTime.now());
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
Expand Down

0 comments on commit 492aee3

Please sign in to comment.