Tôi đã cố gắng sử dụng FileLock
để có được truy cập độc quyền vào một tập tin để:FileLock hoạt động như thế nào?
- xóa nó
- đổi tên nó
- ghi vào nó
Bởi vì trên Windows (ít nhất) có vẻ như bạn không thể xóa, đổi tên hoặc ghi vào một tệp đã được sử dụng. Mã tôi đã viết trông giống như sau:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
public abstract class LockedFileOperation {
public void execute(File file) throws IOException {
if (!file.exists()) {
throw new FileNotFoundException(file.getAbsolutePath());
}
FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
try {
// Get an exclusive lock on the whole file
FileLock lock = channel.lock();
try {
doWithLockedFile(file);
} finally {
lock.release();
}
} finally {
channel.close();
}
}
public abstract void doWithLockedFile(File file) throws IOException;
}
Dưới đây là một số kiểm tra đơn vị chứng minh sự cố. Bạn sẽ cần phải có Apache commons-io trên classpath của bạn để chạy thử nghiệm thứ 3.
import java.io.File;
import java.io.IOException;
import junit.framework.TestCase;
public class LockedFileOperationTest extends TestCase {
private File testFile;
@Override
protected void setUp() throws Exception {
String tmpDir = System.getProperty("java.io.tmpdir");
testFile = new File(tmpDir, "test.tmp");
if (!testFile.exists() && !testFile.createNewFile()) {
throw new IOException("Failed to create test file: " + testFile);
}
}
public void testRename() throws IOException {
new LockedFileOperation() {
@Override
public void doWithLockedFile(File file) throws IOException {
if (!file.renameTo(new File("C:/Temp/foo"))) {
fail();
}
}
}.execute(testFile);
}
public void testDelete() throws IOException {
new LockedFileOperation() {
@Override
public void doWithLockedFile(File file) throws IOException {
if (!file.delete()) {
fail();
}
}
}.execute(testFile);
}
public void testWrite() throws IOException {
new LockedFileOperation() {
@Override
public void doWithLockedFile(File file) throws IOException {
org.apache.commons.io.FileUtils.writeStringToFile(file, "file content");
}
}.execute(testFile);
}
}
Không có bài kiểm tra nào vượt qua. 2 đầu tiên thất bại, và ném cuối cùng ngoại lệ này:
java.io.IOException: The process cannot access the file because another process has locked a portion of the file
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:247)
at org.apache.commons.io.IOUtils.write(IOUtils.java:784)
at org.apache.commons.io.IOUtils.write(IOUtils.java:808)
at org.apache.commons.io.FileUtils.writeStringToFile(FileUtils.java:1251)
at org.apache.commons.io.FileUtils.writeStringToFile(FileUtils.java:1265)
Nó có vẻ như phương pháp lock()
đặt một khóa trên các tập tin mà sau đó ngăn cản tôi từ đổi tên/xóa/viết nó. Giả định của tôi là khóa tệp sẽ cho tôi quyền truy cập độc quyền vào tệp, vì vậy tôi có thể đổi tên/xóa/ghi nó mà không phải lo lắng về việc liệu có quá trình nào khác cũng đang truy cập vào tệp hay không.
Hoặc tôi là sự hiểu lầm FileLock
hoặc đó không phải là giải pháp thích hợp cho vấn đề của tôi.
Vui lòng đăng theo dõi ngăn xếp và kiểm tra đơn vị. – Woot4Moo
Tôi đã cập nhật câu hỏi để bao gồm kiểm tra đơn vị và theo dõi ngăn xếp –
Bạn có thể khóa trên một số tệp "khác" (như tệp kiểm soát) trong khi bạn xóa tệp này ... – rogerdpack