Ben Cheng
Ben Cheng

Reputation: 779

Why File can be moved when file lock acquired by FileChanel.open() instead of RandomAccessFile.getChannel()

I am testing NIO File Lock acquired by FileChannel.open() and RandonAccessFile.getChanel().

It is found that the file that FileLock acquired by FileChannel.open() can be move while FileLock acquired by RandonAccessFile.getChanel() do not.

FileChannel.open()

        File file = new File("../tmp/test.txt");
        FileChannel fileChannel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE);
        FileLock fileLock = fileChannel.lock();
        System.out.println("file locked");
        boolean result = file.renameTo(new File("../tmp/test2.txt"));
        System.out.println("rename result " + result);
        fileLock.release();
        fileChannel.close();

RandonAccessFile.getChanel()

        File file = new File("../tmp/test.txt");
        RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rws");
        FileChannel newChannel = (randomAccessFile).getChannel();
        FileLock fileLock = newChannel.lock();
        System.out.println("File locked");
        boolean result = file.renameTo(new File("../tmp/test2.txt"));
        System.out.println("rename result " + result);

Upvotes: 0

Views: 564

Answers (1)

Stephen C
Stephen C

Reputation: 718758

Behavior of Java file locks are highly platform specific, and so is the behavior of renameTo, including its interaction with files that are explicitly locked or are "in use" in other ways.

In the case of Windows, some file "open" operations will lock the entire file, and rename doesn't work on locked file. (Indeed, I suspect that the version of your code using getChannel() would fail even if you commented out the lock() call. But I don't have a Windows machine to test this.)

By contrast, Linux doesn't lock files when you open them, and you can rename an open file.

How to deal with this?

  • If you want your code to be cross-platform, you need to be extremely conservative. For example, don't attempt to rename a file that your application currently has open. Close all file "handles" before you rename.

  • Alternatively, write your code to be aware of the platform, and do different things on different platforms as required. (I can't advise precisely what, because your example doesn't tell us what you are actually trying to achieve.)

Upvotes: 1

Related Questions