Wolfgang Baltes wolfgang.baltes at
Mon Jan 10 09:49:32 PST 2011

On 2011-01-10 07:03, Alan Bateman wrote:
> Wolfgang Baltes wrote:
>> Hi Alan,
>> I took the WatchDir sample code and modified it as follows:
>> - The directory parsing and event loop runs in a separate thread, 
>> which allows me to delete files and directories programmatically.
>> - Added a few extra console outputs to better catch what is going on.
>> - In the event loop, added a section to catch the particular 
>> condition in which we are interested.
>> The bottom line of what I found is that the behavior changes 
>> depending on whether the deleted subdirectory is empty or not. To 
>> reproduce:
>> 1: Change the code to create a parent directory to your liking. This 
>> is in line 241: final Path dir = Paths.get("c:\\watchtest");
>> 2: Run the code without other modification. It will create the before 
>> mentioned directory, plus a subdirectory, plus two files in that 
>> subdirectory, then waits for something to happen.
>> 3: Manually delete "subdir". The output is:
>>       Scanning c:\watchtest ...
>>       register: c:\watchtest
>>       register: c:\watchtest\subdir
>>       Done with registering directories.
>>       ENTRY_DELETE: c:\watchtest\subdir
>>       c:\watchtest\subdir does not exist... ... but key is valid.
>>       ENTRY_MODIFY: c:\watchtest\subdir\file1.txt
>>       ENTRY_MODIFY: c:\watchtest\subdir\file2.txt
>> 4: Kill the thread and start over.
>> 5: Manually delete first the two files in subdir, and then subdir. 
>> The output is:
>>       Scanning c:\watchtest ...
>>       register: c:\watchtest
>>       register: c:\watchtest\subdir
>>       Done with registering directories.
>>       ENTRY_DELETE: c:\watchtest\subdir\file1.txt
>>       ENTRY_MODIFY: c:\watchtest\subdir
>>       ENTRY_DELETE: c:\watchtest\subdir\file2.txt
>>       ENTRY_MODIFY: c:\watchtest\subdir
>>       Removing watch key for c:\watchtest\subdir.
>>       ENTRY_DELETE: c:\watchtest\subdir
>> 6: You can kill the watch thread by deleting directory "watchtest".
>> 7: You can remove the comments from lines 265 to 273 to automate step 5.
>> For me it is important to make step 3 above work correctly. This is 
>> what a user would do when a directory needs to be removed manually.
>> I hope this helps. Please let me know how I can be of further help.
>> Wolfgang.
> Continuing the thread from December 16.  I followed the instructions 
> above and duplicated the issue you are seeing on Windows Server 2008 
> R2. I couldn't duplicate it on Windows XP. I need to debug it further 
> but it looks like we are just aren't getting any notification from 
> Windows to indicate that watch on subdir is no longer valid. At step 3 
> the event you are seeing is for directory watchtest to say that an 
> entry has been deleted. I'll send mail once I've had time to debug it 
> further.
> -Alan.
Hi Alan,

thanks for the update. I look forward to hearing more from you. As a 
reminder, my system is Windows 7 64 bit, running Java 32 bit.

I would like to take this opportunity to provide some feedback on some 
of the NIO2 classes. As I am using them quite a lot in the program I am 
working on, I have a short wish list. I have seen emails talking about 
some of the items, but did not see a conclusion:

1: WatchEvent.context(): it would be nice to get a complete path, not 
just a relative path. I can always build the relative path from a 
complete path, but the other way around forces me to store the parent 
path and do some extra work. /Complete path/ could be the concatenation 
of original or real (as in toRealPath) parent path that was used to 
obtain the WatchKey, and the name of the directory or file which caused 
the event. The original parent would probably be better because it 
maintains the information that was put into the system and one can 
always convert it to the real path.

2: WatchService class: provide a isClosed() method. This is convenient 
when multiple threads need to share this knowledge. It is simpler than 
having to catch the ClosedWatchServiceException in one thread and then 
to propagate it to other threads. All other methods that throw this 
exception have some side-effect.

3: Path class:
3.1: It would be nice to have a getExtension() method.
3.2: Same for getNameWithoutExtension() method.

4: Path or Paths class: provide a static method that returns an empty 
Path array. See Item 43 in Joshua Bloch, Effective Java, Second Edition, 
page 201. I use this systematically, and am frustrated that I have to 
redefine empty arrays again and again, instead of having them in the 
base library.

5: It would be nice to have some predefined Path instances, such as the 
"." path (= current path), and possibly a "null" path. The first acts as 
an identity element (as in mathematical groups), because its effect is 
neutral to all relevant Path operations. The second is for use in Path 
collections which do not accept null. I understand that this is a little 
bit tricky if you want this instance to have special behavior in regard 
to some methods.

Another comment is relative to the documentation: almost all NIO methods 
throw IOException. That's a pretty large group of exceptions, many of 
which can probably appear at any time, but only a few of which have 
particular meaning in a specific context. For example, the watch events 
appear much faster than the file system finishes writing a file. The 
documentation says nothing about which exception I should expect if I 
try to access the file to soon (FileSystemException). I think that 
providing this type of information would help a lot of people.

-------------- next part --------------
An HTML attachment was scrubbed...

More information about the nio-dev mailing list