我正在使用 NIO 文件通道来管理文件并锁定它们。到目前为止它可以工作,但是当我使用 NIO 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) {
}
}
}
Run Code Online (Sandbox Code Playgroud)
经过进一步研究,我注意到使用RandomAccessFile将锁定文件以避免删除,因为它创建了一个 文件描述符,基本上在下划线操作系统上打开一个句柄。因此,使用 RAF 确实提供了所需的结果:

使用的代码:
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) {
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是我想知道是否可以仅使用 NIO 将其存档。由于随机访问文件在 IO 包上。
未指定 FileLock 以防止删除。它仅被指定为与其他文件锁交互,因此您已经深入了解平台相关的行为。如果 RandomAccessFile 以某种方式执行您想要的操作,您可能会被它卡住,但您不能依赖它。
注意当然 FileChannel.open() 使用 FileDescriptor、句柄等。
| 归档时间: |
|
| 查看次数: |
2017 次 |
| 最近记录: |