我的Java程序想要读取一个文件,该文件可以被写入其中的另一个程序锁定。我需要检查文件是否被锁定,如果是,请等待它是免费的。我如何实现这一目标?
Java程序在Windows 2000服务器上运行。
答案 0 :(得分:29)
应该适用于Windows:
File file = new File("file.txt");
boolean fileIsNotLocked = file.renameTo(file);
答案 1 :(得分:13)
在使用Sun的JVM的Windows下,FileLocks应该可以正常工作,尽管JavaDocs的可靠性相当模糊(取决于系统)。
然而,如果您只需要在Java程序中识别出一些其他程序正在锁定文件,那么您不必费力地使用FileLocks,而只需尝试写入文件,如果被锁定将失败。您最好在实际系统上尝试此操作,但我看到以下行为:
File f = new File("some-locked-file.txt");
System.out.println(f.canWrite()); // -> true
new FileOutputStream(f); // -> throws a FileNotFoundException
这很奇怪,但是如果你没有把平台独立性计算得太高而你的系统显示出相同的行为,你可以把它放在一个效用函数中。
对于当前的Java版本,遗憾的是无法获知有关文件状态更改的信息,因此如果您需要等到文件可以写入,则必须时不时地尝试检查其他进程是否已发布它的锁。我不确定,但是使用Java 7,可能会使用新的WatchService来了解这些更改。
答案 2 :(得分:5)
在使用该文件的所有Java应用程序中使用FileLock
,并使它们在同一JVM中运行。否则,这不能可靠地完成。
答案 3 :(得分:2)
如果多个进程(可以是Java和非Java的混合)可能正在使用该文件,请使用FileLock
。成功使用文件锁的关键是要记住它们只是“建议性的”。如果您检查锁定,则保证锁定可见,但如果您忘记,它将不会阻止您对文件执行操作。访问该文件的所有进程都应设计为使用锁定协议。
答案 4 :(得分:2)
您可以尝试获取该文件的独占锁定。只要无法获得独占锁,另一个程序就会对文件进行锁定(独占或共享)。
答案 5 :(得分:2)
最好的方法是使用FileLock,但在我的情况下(jdk 1.6)我尝试了成功:
public static boolean isFileUnlocked(File file) {
try {
FileInputStream in = new FileInputStream(file);
if (in!=null) in.close();
return true;
} catch (FileNotFoundException e) {
return false;
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
答案 6 :(得分:0)
仅在Windows上测试: 您可以检查该文件是否被锁定为以下增强 venergiac 答案: 检查(file.exist())文件是否存在,但FileNotFoundException意味着被锁定! 您会注意到此消息(进程无法访问该文件,因为它正由另一个进程使用)
public static boolean isFilelocked(File file) {
try {
FileInputStream in = new FileInputStream(file);
in.close();
return false;
} catch (FileNotFoundException e) {
if(file.exist()){
return true;
}
return false;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
答案 7 :(得分:0)
改进了Amjad Abdul-Ghani的回答,我发现在尝试从文件中读取之前没有产生错误
public static boolean isFilelocked(File file) {
try {
try (FileInputStream in = new FileInputStream(file)) {
in.read();
return false;
}
} catch (FileNotFoundException e) {
return file.exists();
} catch (IOException ioe) {
return true;
}
}
答案 8 :(得分:0)
我尝试了在Windows上访问Linux Smb共享的答案(@vlad)的组合,它为我工作。第一部分足以用于Excel之类的锁定,但对于某些编辑器而言则不够。我添加了第二部分(重命名)来测试这两种情况。
public static boolean testLockFile(File p_fi) {
boolean bLocked = false;
try (RandomAccessFile fis = new RandomAccessFile(p_fi, "rw")) {
FileLock lck = fis.getChannel().lock();
lck.release();
} catch (Exception ex) {
bLocked = true;
}
if (bLocked)
return bLocked;
// try further with rename
String parent = p_fi.getParent();
String rnd = UUID.randomUUID().toString();
File newName = new File(parent + "/" + rnd);
if (p_fi.renameTo(newName)) {
newName.renameTo(p_fi);
} else
bLocked = true;
return bLocked;
}
答案 9 :(得分:0)
对于Windows,您还可以使用:
checkAppPermissions: function () {
return new Promise(function (resolve) {
let permissions = cordova.plugins.permissions;
let permissionList = [
permissions.CAMERA,
permissions.RECORD_AUDIO,
permissions.WRITE_EXTERNAL_STORAGE
];
let acceptedCount = 0;
permissionList.forEach(perm => {
permissions.checkPermission(perm, function (status) {
if (status.hasPermission) {
acceptedCount++;
console.log('checkAppPermission: checkPermission: Current acceptedCount: ', acceptedCount);
if (acceptedCount === permissionList.length) {
console.log('checkAppPermission: checkPermission: All permissions accepted.');
resolve();
}
} else permissions.requestPermission(perm, function () {
console.log('checkAppPermission: requestPermission: All permissions accepted.');
resolve();
}, null);
}, null);
});
});
},
如果文件仅被锁定(例如,通过MS Word锁定),则会出现异常:
new RandomAccessFile(file, "rw")
。
这样,您无需仅为了检查而打开/关闭流。
注意-如果文件未排他地锁定(例如在Notepad ++中打开),则不会例外。