简体   繁体   English

Java - 锁定文件以进行独占访问

[英]Java - locking a file for exclusive access

My problem is this: I'm using a WatchService to get notified about new files in a specific folder, now if a file gets moved/copied or created in said folder an event gets triggered and the name of the new file gets returned.我的问题是这样的:我正在使用WatchService来获取有关特定文件夹中新文件的通知,现在如果在所述文件夹中移动/复制或创建文件,则会触发事件并返回新文件的名称。 The problem now is, if I try to access the file and it is not fully there yet (eg the copy is still in progress) an exception gets raised.现在的问题是,如果我尝试访问该文件但它尚未完全存在(例如复制仍在进行中),则会引发异常。 What i tried was to do something like this:我试过的是做这样的事情:

RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
FileChannel fc = raf.getChannel();
FileLock lck = fc.lock();

But even if a lock gets acquired, sometimes still an Exception gets raised if I try to write to the file because another process has still an open handle to it.但是,即使获得了锁,如果我尝试写入文件,有时仍然会引发异常,因为另一个进程仍然有一个打开的句柄。

Now, how can a file in Java be locked for truly exclusive access?现在,如何锁定 Java 中的文件以进行真正的独占访问?

For me, the statement对我来说,声明

RandomAccessFile raf = new RandomAccessFile(fileName, "rw"); 

returns a FileNotFoundException if I cannot acquire a lock on the file.如果我无法获取文件锁定,则返回 FileNotFoundException。 I catch the filenotfound exception and treat it...我捕获了 filenotfound 异常并对其进行处理...

public static boolean isFileLocked(String filename) {
    boolean isLocked=false;
    RandomAccessFile fos=null;
    try {
        File file = new File(filename);
        if(file.exists()) {
            fos=new RandomAccessFile(file,"rw");
        }
    } catch (FileNotFoundException e) {
        isLocked=true;
    }catch (Exception e) {
        // handle exception
    }finally {
        try {
            if(fos!=null) {
                fos.close();
            }
        }catch(Exception e) {
            //handle exception
        }
    }
    return isLocked;
}

you could run this in a loop and wait until you get a lock on the file.您可以在循环中运行它并等待直到获得文件锁定。 Wouldn't the line行不行

FileChannel fc = raf.getChannel();

never reach if the file is locked?如果文件被锁定,永远不会到达? You will get a FileNotFoundException thrown..你会得到一个 FileNotFoundException 抛出..

its better not to use classes in thejava.io package, instead use the java.nio package .最好不要使用 java.io 包中的类,而是使用 java.nio 包。 The latter has a FileLock class that you can use for a lock to a FileChannel.后者有一个 FileLock 类,可用于锁定 FileChannel。

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();

        /*
           use channel.lock OR channel.tryLock();
        */

        // 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 - if it is not null!
        if( lock != null ) {
            lock.release();
        }

        // Close the file
        channel.close();
    } catch (Exception e) {
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM