title: How does FileLock work?
body: <p>I've been trying to use <code>FileLock</code> to get exclusive access to a file in order to:</p>
  
  <ul>
  <li>delete it</li>
  <li>rename it</li>
  <li>write to it</li>
  </ul>
  
  <p>Because on Windows (at least) it seems that you cannot delete, rename, or write to a file that is already in use. The code I've written looks something like this:</p>
  
  <pre><code>import java.io.File;
  import java.io.FileNotFoundException;
  import java.io.IOException;
  import java.io.RandomAccessFile;
  import java.nio.channels.FileChannel;
  import java.nio.channels.FileLock;
  
  public abstract class LockedFileOperation {
  
      public void execute(File file) throws IOException {
  
          if (!file.exists()) {
              throw new FileNotFoundException(file.getAbsolutePath());
          }
  
          FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
  
          try {
              // Get an exclusive lock on the whole file
              FileLock lock = channel.lock();
  
              try {
                  doWithLockedFile(file);
              } finally {
                  lock.release();
              }
          } finally {
              channel.close();
          }
      }
  
      public abstract void doWithLockedFile(File file) throws IOException;
  }
  </code></pre>
  
  <p>Here are some unit tests that demonstrate the problem. You'll need to have Apache commons-io on your classpath to run the 3rd test.</p>
  
  <pre><code>import java.io.File;
  import java.io.IOException;
  
  import junit.framework.TestCase;
  
  public class LockedFileOperationTest extends TestCase {
  
      private File testFile;
  
      @Override
      protected void setUp() throws Exception {
  
          String tmpDir = System.getProperty("java.io.tmpdir");
          testFile = new File(tmpDir, "test.tmp");
  
          if (!testFile.exists() &amp;&amp; !testFile.createNewFile()) {
              throw new IOException("Failed to create test file: " + testFile);
          }
      }
  
      public void testRename() throws IOException {
          new LockedFileOperation() {
  
              @Override
              public void doWithLockedFile(File file) throws IOException {
                  if (!file.renameTo(new File("C:/Temp/foo"))) {
                      fail();
                  }
              }
          }.execute(testFile);
      }
  
      public void testDelete() throws IOException {
          new LockedFileOperation() {
  
              @Override
              public void doWithLockedFile(File file) throws IOException {
                  if (!file.delete()) {
                      fail();
                  }
              }
          }.execute(testFile);
      }
  
      public void testWrite() throws IOException {
          new LockedFileOperation() {
  
              @Override
              public void doWithLockedFile(File file) throws IOException {
                  org.apache.commons.io.FileUtils.writeStringToFile(file, "file content");
              }
          }.execute(testFile);
      }
  }
  </code></pre>
  
  <p>None of the tests pass. The first 2 fail, and the last throws this exception:</p>
  
  <pre><code>java.io.IOException: The process cannot access the file because another process has locked a portion of the file
      at java.io.FileOutputStream.writeBytes(Native Method)
      at java.io.FileOutputStream.write(FileOutputStream.java:247)
      at org.apache.commons.io.IOUtils.write(IOUtils.java:784)
      at org.apache.commons.io.IOUtils.write(IOUtils.java:808)
      at org.apache.commons.io.FileUtils.writeStringToFile(FileUtils.java:1251)
      at org.apache.commons.io.FileUtils.writeStringToFile(FileUtils.java:1265)
  </code></pre>
  
  <p>It seems like the <code>lock()</code> method places a lock on the file which then prevents me from renaming/deleting/writing it. My assumption was that locking the file would give me exclusive access to the file, so I could then rename/delete/write it without worrying about whether any other process is also accessing it.</p>
  
  <p>Either I'm misunderstanding <code>FileLock</code> or it's not an appropriate solution for my problem.</p>