How to atomically rename a file in Java, even if the dest file already exists?

前端 未结 8 2092
难免孤独
难免孤独 2020-12-09 07:55

I have a cluster of machines, each running a Java app.

These Java apps need to access a unique resource.txt file concurently.

I need to atomical

8条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-09 08:05

    On Linux (and I believe Solaris and other UNIX operating systems), Java's File.renameTo() method will overwrite the destination file if it exists, but this is not the case under Windows.

    To be cross platform, I think you'd have to use file locking on resource.txt and then overwrite the data.

    The behavior of the file lock is platform-dependent. On some platforms, the file lock is advisory, which means that unless an application checks for a file lock, it will not be prevented from accessing the file. On other platforms, the file lock is mandatory, which means that a file lock prevents any application from accessing the file.

    try {
        // Get a file channel for the file
        File file = new File("filename");
        FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
    
        // Use the file channel to create a lock on the file.
        // This method blocks until it can retrieve the lock.
        FileLock lock = channel.lock();
    
        // Try acquiring the lock without blocking. This method returns
        // null or throws an exception if the file is already locked.
        try {
            lock = channel.tryLock();
        } catch (OverlappingFileLockException e) {
            // File is already locked in this thread or virtual machine
        }
    
        // Release the lock
        lock.release();
    
        // Close the file
        channel.close();
    } catch (Exception e) {
    }
    

    Linux, by default, uses voluntary locking, while Windows enforces it. Maybe you could detect the OS, and use renameTo() under UNIX with some locking code for Windows?

    There's also a way to turn on mandatory locking under Linux for specific files, but it's kind of obscure. You have to set the mode bits just right.

    Linux, following System V (see System V Interface Definition (SVID) Version 3), lets the sgid bit for files without group execute permission mark the file for mandatory locking

提交回复
热议问题