0

I have a process that will lock the text file and write over the same file with a new text string at random time intervals. And I have written another process, a WatchService that listens to changes in the same directory and then locks the file and reads the content of the file. I believe Locking the file is important here, as I want to make sure only one process can either read/write to the same at one time.

The code only runs successfully to lock the file and write contents to the file and the WatchService is able to detect changes in the directory but it fails to lock and read the content.

Based on the logs, it says that The process cannot access the file because another process has locked a portion of the file but I have explicitly written channel.close() to close the file channel already.

What have I done wrong? What did I misunderstand?

UPDATE: per suggestion below, I have replaced lock with tryLock and release the lock too but it's still not able to run past the line lock = channel.tryLock(); in the WatchFile class. Since it doesn't generate any error, I only found out about this through System.out.println to see where the code got stuck.

// Lock file and write public static void WriteTo throws IOException{ String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss").withZone(ZoneId.of("Asia/Hong_Kong"))); FileOutputStream fos = null; FileChannel channel = null; FileLock lock = null; try{ fos = new FileOutputStream("C:\\Testing\\newTimestamp.txt"); channel = fos.getChannel(); lock = channel.tryLock(); // write to channel byte[] mybytes = order_str.getBytes(); fos.write(mybytes); System.out.println("File Successfully Written !"); } catch(NonWritableChannelException e) { e.printStackTrace(); } finally { lock.release(); channel.close(); fos.close(); } } // Lock file and read contents private static class WatchFile implements Runnable{ public WatchFile(){ } public void run() { try { System.out.println("2. WatchService Started Running @ " + LocalDateTime.now() + " !!!"); Path path = Paths.get("C:\\Testing"); path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE,StandardWatchEventKinds.ENTRY_MODIFY,StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.OVERFLOW); WatchKey key; while((key = watchService.take()) != null) { for(WatchEvent<?> event: key.pollEvents()) { System.out.println("Event time: "+ LocalDateTime.now() + ". Event kind:" + event.kind() + ". File affected: " + event.context() +"."); // only register final Path changed = (Path) event.context(); System.out.println("Changed: " + event.context()); if(changed.endsWith("newTimestamp.txt") && event.kind() == StandardWatchEventKinds.ENTRY_MODIFY) { String line; FileInputStream fis = null; FileChannel channel = null; FileLock lock = null; BufferedReader br = null; try { fis = new FileInputStream("C:\\Testing\\newTimestamp.txt"); channel = fis.getChannel(); lock = channel.tryLock(); br = new BufferedReader(new InputStreamReader(fis)); while((line = br.readLine()) != null) { // process string } } catch(IOException e) { e.printStackTrace(); } finally { if (br != null) { try { br.close(); lock.release(); channel.close(); fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } } key.reset(); } } catch (IOException | InterruptedException e) { e.printStackTrace(); } } } 

Error:

java.io.IOException: The process cannot access the file because another process has locked a portion of the file at java.base/java.io.FileInputStream.readBytes(Native Method) at java.base/java.io.FileInputStream.read(FileInputStream.java:279) at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284) at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326) at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178) at java.base/java.io.InputStreamReader.read(InputStreamReader.java:185) at java.base/java.io.BufferedReader.fill(BufferedReader.java:161) at java.base/java.io.BufferedReader.readLine(BufferedReader.java:326) at java.base/java.io.BufferedReader.readLine(BufferedReader.java:392) 

1 Answer 1

1

I guess you missed to release of the lock. lock.release() OR lock.close()

And it would be more suitable to use channel.tryLock() instead channel.lock()

P.S. be sure to check. Is lock acquired or not:

A lock object representing the newly-acquired lock, or null if the lock could not be acquired because another program holds an overlapping loc

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.