gpt4 book ai didi

java - 如何使用 Java (openjdk 11) 在 Windows 10 中独占锁定文件?

转载 作者:行者123 更新时间:2023-12-01 16:38:14 26 4
gpt4 key购买 nike

我尝试使用 openjdk 11 在 Windows 10 中独占锁定文件,但它无法按预期工作。它应该保证只要锁定到位,除了我自己的进程之外,没有任何进程应该能够编辑/删除/...该文件。

我寻找答案,但它们 a) 相当旧,b) 使用与我相同的代码,并说“这就是它是如何完成的”。

下面是一个简单的示例,它创建一个测试文件,并在获取锁定后等待 10 秒,然后再读取。非共享锁需要打开选项“WRITE”(否则 tryLock 会抛出 UnsupportedOperationException)。

到目前为止的行为:

  • 当我在等待期间删除文件(在 Windows 资源管理器中)时,读取仍会提供文件的原始内容,但在我删除文件时,文件就会从资源管理器概述中消失
  • 当我在等待期间编辑文件时(例如使用 Notepad++ ),编辑器打开文件而没有任何显示内容,我可以编辑并保存,但之后读取返回 -1 并且文件为空

预期行为:

  • 对该文件的任何其他访问都应返回 Windows 错误(文件正在使用中),就像您打开 Word 文档并尝试删除它时一样

我做错了什么?

import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;

public class TestLocking {

public static void main(String[] args) throws Exception {

String filename = "testfile.txt";

Path file = Path.of(filename);
if (!Files.exists(file)) {
String content = "foo";
System.out.format("File '%s' not found - create and fill with '%s'.%n%n", file.toAbsolutePath().toString(),
content);
Files.write(file, content.getBytes(Charset.defaultCharset()));
}

FileChannel filechannel = FileChannel.open(file, StandardOpenOption.READ, StandardOpenOption.WRITE);
FileLock lock = filechannel.tryLock(0, Long.MAX_VALUE, false);

if (lock == null) {
System.out.println("File already locked.");
} else {
System.out.println("File lock aquired.");
Thread.sleep(10000);
System.out.println("reading file..");
ByteBuffer buffer = ByteBuffer.allocate(1000);
int readBytes = filechannel.read(buffer);
System.out.format("read %d bytes.%n", readBytes);
buffer.flip();
final byte[] array = new byte[buffer.remaining()];
buffer.duplicate().get(array);
String s = new String(array, Charset.defaultCharset());
System.out.println("---FILE-CONTENT---");
System.out.println(s);
System.out.println("---FILE---END-----");
// unlock
lock.close();
System.out.println("File lock released.");
}
filechannel.close();
}
}

edit1:忘记了channel.close()

最佳答案

在 Java 中,可以使用 FileChannel 来获取文件锁,FileChannel 为此提供了两种方法 — lock() 和 tryLock()。

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class FileLockTest {
private static final Log LOG = LogFactory.getLog(FileLockTest.class);
private static FileChannel fc;
private static RandomAccessFile randomAccessFile;
public FileLockTest(String fileName) throws FileNotFoundException {
randomAccessFile = new RandomAccessFile(fileName, "rw");
}
public void writeToFileWithLock(String data) {
fc = randomAccessFile.getChannel();
ByteBuffer buffer = null;
try (fc; randomAccessFile; FileLock fileLock = fc.tryLock()) {
if (null != fileLock) {
buffer = ByteBuffer.wrap(data.getBytes());
buffer.put(data.toString().getBytes());
buffer.flip();
while (buffer.hasRemaining())
fc.write(buffer);
}
} catch (OverlappingFileLockException | IOException ex) {
LOG.error("Exception occured while trying to get a lock on File... " + ex.getMessage());
}
}
}

关于java - 如何使用 Java (openjdk 11) 在 Windows 10 中独占锁定文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61914309/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com