Java 7 WatchService - The process cannot access the file because it is being used by another process

file-io, java, java-7, watchservice

Solution

Ok, I found a solution. I don't know if it is the best way to do this, but it works. Unfortunately, file.canRead() and file.canWrite() both return true, even if the file still locked by Windows. So I discovered that if I try to "rename" it with the same name, I know if Windows is working on it or not. So this is what I did:

    while(!sourceFile.renameTo(sourceFile)) {
        // Cannot read from file, windows still working on it.
        Thread.sleep(10);
    }

Problem

I followed the Watching a Directory for Changes Java7 nio2 tutorial to recursively monitor the entire contents of a directory using the code sample WatchDir.java. The code looks like this: ``` // Get list of events for the watch key. for (WatchEvent<?> event : key.pollEvents()) { // This key is registered only for ENTRY_CREATE events, but an OVERFLOW event // can occur regardless if events are lost or discarded. if (event.kind() == OVERFLOW) { continue; } // Context for directory entry event is the file name of entry. @SuppressWarnings("unchecked") WatchEvent<Path> ev = (WatchEvent<Path>)event; Path fileName = ev.context(); Path fullPath = dir.resolve(fileName); try { // Print out event. System.out.print("Processing file: " + fileName); processed = fileProcessor.processFile(fullPath); System.out.println("Processed = " + processed); if (processed) { // Print out event. System.out.println(" - Done!"); } } catch (FileNotFoundException e) { System.err.println("Error message: " + e.getMessage()); } catch (IOException e) { System.err.println("Error processing file: " + fileName.toString()); System.err.println("Error message: " + e.getMessage()); } ``` Ok, so the problem (where I am sure doing something stupid) is here: ``` processed = fileProcessor.processFile(fullPath); ``` And what it does is something like this: ``` public synchronized boolean processFile(Path fullPath) throws IOException { String line; String[] tokens; String fileName = fullPath.getFileName().toString(); String fullPathFileName = fullPath.toString(); // Create the file. File sourceFile = new File(fullPath.toString()); // If the file does not exist, print out an error message and return. if (sourceFile.exists() == false) { System.err.println("ERROR: " + fullPathFileName + ": No such file"); return false; } // Check file extension. if (!getFileExtension(fullPathFileName).equalsIgnoreCase("dat")) { System.out.println(" - Ignored."); return false; } // Process source file. try (BufferedReader bReader = new BufferedReader(new FileReader(sourceFile))) { int type; // Process each line of the file. while (bReader.ready()) { // Get a single line. line = bReader.readLine(); // Get line tokens. tokens = line.split(delimiter); // Get type. type = Integer.parseInt(tokens[0]); switch (type) { // Type 1 = Salesman. case 1: -> Call static method to process tokes. break; // Type 2 = Customer. case 2: -> Call static method to process tokes. break; // Type 3 = Sales. case 3: -> Call static method to process tokes. break; // Other types are unknown! default: System.err.println("Unknown type: " + type); break; } } PrintStream ps = null; try { // Write output file. // Doesn't matter. } finally { if (ps != null) { ps.close(); } } return true; } } ``` The first time I handle an event, it all works fine! Even if there is more than 1 file to process. But in the consecutive times, I get this error message: The process cannot access the file because it is being used by another process What am I doing wrong here? What can I do to process the consecutive files with sucess? Two important notes that I forgot to mention: - I'm using Windows 7. - When I run the application in debug mode, it works. EDIT: If I add a sleep before I try to use the file, it works: ``` Thread.sleep(500); // Process source file. try (BufferedReader bReader = new BufferedReader(new FileReader(sourceFile))) { ``` So, is it possible to be Windows that is not unlocking the files in time? How can I fix that (in a proper way)?

Original source