Mega Code Archive

 
Categories / Java / File Input Output
 

Demonstrates file locking and simple file read and write operations using java nio channels FileChannel

/*  * Copyright (c) 2004 David Flanagan.  All rights reserved.  * This code is from the book Java Examples in a Nutshell, 3nd Edition.  * It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.  * You may study, use, and modify it for any non-commercial purpose,  * including teaching and use in open-source projects.  * You may distribute it non-commercially as long as you retain this notice.  * For a commercial use license, or to purchase the book,   * please visit http://www.davidflanagan.com/javaexamples3.  */ //package je3.nio; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; /**  * Lock.java: this class demonstrates file locking and simple file read and  * write operations using java.nio.channels.FileChannel. It uses file locking to  * prevent two instances of the program from running at the same time.  */ public class Lock {   public static void main(String args[]) throws IOException, InterruptedException {     RandomAccessFile file = null; // The file we'll lock     FileChannel f = null; // The channel to the file     FileLock lock = null; // The lock object we hold     try { // The finally clause closes the channel and releases the lock       // We use a temporary file as the lock file.       String tmpdir = System.getProperty("java.io.tmpdir");       String filename = Lock.class.getName() + ".lock";       File lockfile = new File(tmpdir, filename);       // Create a FileChannel that can read and write that file.       // Note that we rely on the java.io package to open the file,       // in read/write mode, and then just get a channel from it.       // This will create the file if it doesn't exit. We'll arrange       // for it to be deleted below, if we succeed in locking it.       file = new RandomAccessFile(lockfile, "rw");       f = file.getChannel();       // Try to get an exclusive lock on the file.       // This method will return a lock or null, but will not block.       // See also FileChannel.lock() for a blocking variant.       lock = f.tryLock();       if (lock != null) {         // We obtained the lock, so arrange to delete the file when         // we're done, and then write the approximate time at which         // we'll relinquish the lock into the file.         lockfile.deleteOnExit(); // Just a temporary file         // First, we need a buffer to hold the timestamp         ByteBuffer bytes = ByteBuffer.allocate(8); // a long is 8 bytes         // Put the time in the buffer and flip to prepare for writing         // Note that many Buffer methods can be "chained" like this.         bytes.putLong(System.currentTimeMillis() + 10000).flip();         f.write(bytes); // Write the buffer contents to the channel         f.force(false); // Force them out to the disk       } else {         // We didn't get the lock, which means another instance is         // running. First, let the user know this.         System.out.println("Another instance is already running");         // Next, we attempt to read the file to figure out how much         // longer the other instance will be running. Since we don't         // have a lock, the read may fail or return inconsistent data.         try {           ByteBuffer bytes = ByteBuffer.allocate(8);           f.read(bytes); // Read 8 bytes from the file           bytes.flip(); // Flip buffer before extracting bytes           long exittime = bytes.getLong(); // Read bytes as a long           // Figure out how long that time is from now and round           // it to the nearest second.           long secs = (exittime - System.currentTimeMillis() + 500) / 1000;           // And tell the user about it.           System.out.println("Try again in about " + secs + " seconds");         } catch (IOException e) {           // This probably means that locking is enforced by the OS           // and we were prevented from reading the file.         }         // This is an abnormal exit, so set an exit code.         System.exit(1);       }       // Simulate a real application by sleeping for 10 seconds.       System.out.println("Starting...");       Thread.sleep(10000);       System.out.println("Exiting.");     } finally {       // Always release the lock and close the file       // Closing the RandomAccessFile also closes its FileChannel.       if (lock != null && lock.isValid())         lock.release();       if (file != null)         file.close();     }   } }