java - 如何使用 NIO 包锁定文件以避免删除

标签 java windows nio

我正在使用 NIO 文件 channel 来管理文件并锁定它们。到目前为止它有效,但是当我使用 NIO File Lock 锁定文件时,它会锁定文件,因此无法更改文件内容。例如,如果我尝试在记事本上编辑文本文件,它会显示以下错误消息: File Lock

这是预期的结果,但是如果我尝试从 Windows 资源管理器中删除文件(我还没有在其他操作系统上测试过,可能也有可能)它会允许我,这是不希望的,我想知道是否可以打开文件句柄

使用的代码:

private static final byte[] MessageBytes;
static {
    byte tmp[];
    try {
        tmp = "Hello World".getBytes("UTF-8");
    } catch (UnsupportedEncodingException ex) {
        //if fail get the bytes in whatever the java VM charset sets as default
        tmp = "Hello World".getBytes();
    }
    MessageBytes = tmp;
}
private static final String Filename = "Lock_test.txt";

 private static void createFileandLock() {
    Path FilePath = Paths.get(Filename);
    FileChannel OpenFCh;
    try {
        OpenFCh = FileChannel.open(FilePath, StandardOpenOption.CREATE,
                StandardOpenOption.READ, StandardOpenOption.WRITE
        //                    ,StandardOpenOption.APPEND
        );
        System.out.println("File Channel is Open.");
    } catch (IOException err) {
        OpenFCh = null;
    }
    if (OpenFCh != null) {
        FileLock Lock = null;
        try {
            Lock = OpenFCh.lock();
        } catch (IOException err) {
            System.out.println("Unable To Lock the File.");
        }
        try {
            OpenFCh.write(ByteBuffer.wrap(MessageBytes));
            OpenFCh.force(false);
            System.out.println("Message Recorded");
        } catch (IOException ex) {
            System.out.println("Unable To write data into file");
        }
        try {
            // at this point file still locked and open.
            //lets wait for input and meanwhile ask to delete the file. 
            System.out.print("Please Try to delete file at: ");
            System.out.println(FilePath.toString());
            System.out.println("Press Enter to Continue");
            System.in.read();
        } catch (IOException ex) {
        }
        if (Lock != null) {
            try {
                Lock.close();
            } catch (IOException ex) {
            }
        }
        try {
            OpenFCh.close();
        } catch (IOException ex) {
        }
    }
}

经过进一步研究,我注意到使用 RandomAccessFile将锁定文件避免删除,因为它创建了一个 File Descriptor基本上在带下划线的操作系统上打开一个句柄。 所以使用 RAF 确实提供了预期的结果: File Open Message

使用的代码:

private static void createRAFileandLock() {
    RandomAccessFile RAf;
    try {
        RAf = new RandomAccessFile(Filename, "rw");
    } catch (FileNotFoundException ex) {
        //since is open as RW shold not trigger.
        RAf = null;
    }
    if (RAf != null) {
        FileChannel OpenFCh = RAf.getChannel();
        FileLock Lock = null;
        try {
            Lock = OpenFCh.lock();
        } catch (IOException err) {
            System.out.println("Unable To Lock the File.");
        }
        try {
            OpenFCh.write(ByteBuffer.wrap(MessageBytes));
            OpenFCh.force(false);
            System.out.println("Message Recorded");
        } catch (IOException ex) {
            System.out.println("Unable To write data into file");
        }
         // at this point file still locked and open.
        //lets wait for input and meanwhile ask to delete the file. 
        try {
            System.out.print("Please Try to delete file at: ");
            System.out.println(Filename);
            System.out.println("Press Enter to Continue");
            System.in.read();
        } catch (IOException ex) {
        }
        if (Lock != null) {
            try {
                Lock.close();
            } catch (IOException ex) {
            }
        }
        try {
            OpenFCh.close();
            RAf.close();
        } catch (IOException ex) {
        }
    }
}

但是我想知道是否可以只使用 NIO 来存档它。由于随机访问文件位于 IO 包中。

最佳答案

未指定 FileLock 以防止删除。它仅指定与其他文件锁交互,因此您已经深入研究了依赖于平台的行为。如果 RandomAccessFile 以某种方式做你想做的事,你可能会坚持使用它,但你不能依赖它。

注意,当然 FileChannel.open() 使用 FileDescriptor、句柄等。

关于java - 如何使用 NIO 包锁定文件以避免删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23577576/

相关文章:

java - 动态裁剪签名图像

java nio 否定 glob 模式

c - 0A 转换为 C 中的 0D0A

node.js - GENERATE_SOURCEMAP=false 问题

Java 8 : read files with special characters in name

java - 进程无法访问文件,因为该文件正在被另一个进程使用

java - hbm2ddl.auto= create/create-drop 也会删除数据吗?

java - 用于Elasticsearch的Java Transport Client抛出NoNodeAvailableException

java - WebView - 无法添加窗口 - token null 不适用于应用程序

windows - 庆典 : nano: command not found at Windows git bash