检查目录及其内容是否已锁定的最佳方法是什么?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了检查目录及其内容是否已锁定的最佳方法是什么?相关的知识,希望对你有一定的参考价值。
假设我将包含目录路径的字符串传递给随机方法。在此方法开始工作之前,应检查目录或其任何内容是否已锁定。我认为这将是一个简单的任务,但事实证明我得到了一些不太简单的代码。您有什么建议如何改进它或至少缩短它?
如果你认为这已经是最好的解决方案,那就给它一个投票并继续解决实际问题:P
public static boolean checkLocks(String path) {
File f = new File(path);
if(f.isDirectory()) {
boolean ans = true;;
String files[] = f.list();
for (String file : files) {
File ff = new File(f, file);
ans = checkLocks(ff.toString());
if(!ans){
break;
}
}
return ans;
} else {
try {
RandomAccessFile stream = new RandomAccessFile(path, "rw");
FileChannel channel = stream.getChannel();
FileLock lock = null;
try {
lock = channel.tryLock();
} catch (final OverlappingFileLockException e) {
stream.close();
channel.close();
System.out.println("File at "+path+" locked");
return false;
}
stream.close();
channel.close();
return true;
} catch (IOException eio) {
System.out.println("File at "+path+" does not exits");
return false;
}
}
}
答案
检查目录中的每个文件都会让我觉得很慢并且容易出现竞争条件。在您的示例中,您将立即获取目录中的文件列表,然后对每个文件进行测试;同时创建者线程可能仍在添加文件。即使列表中的每个文件都可访问,创建者也可能无法完成编写目录。
它有些老派而且不是很花哨,但我会在创建过程中使用临时目录名称,或者将锁定文件写为第一个文件,并在创建者完成时将其删除。
在第一种情况下:
String baseDirectory = "{whatever}";
String workDirectory = "workDirectory" + counter;
Path tempPath = FileSystems.getDefault().getPath(baseDirectory, ".temp_" + workDirectory);
Path workPath = FileSystems.getDefault().getPath(baseDirectory, workDirectory);
Files.createDirectory(tempPath);
// Write the contents of the directory.
// [...]
Files.move(tempPath, workPath, CopyOptions.ATOMIC_MOVE);
在第二种情况:
String baseDirectory = "{whatever}";
String workDirectory = "workDirectory" + counter;
Path workPath = FileSystems.getDefault().getPath(baseDirectory, workDirectory);
Files.createDirectory(workPath);
Path lockFile = workPath.resolve("LOCKFILE");
Files.createFile(lockFile);
// Write the contents of the directory.
// [...]
Files.delete(lockFile);
两种情况下的想法都是创建者任务在创建目录时明确发出信号。如果您只是等待操作暂停,它可能只是等待大缓冲区加载网络。
另一答案
我认为最简单的方法是使用Files
类及其is*
方法,如isReadable
和isWritable
。
if (Files.isReadable(new File(filepath).toPath()) &&
Files.isWritable(new File(filepath).toPath()))
{
/* do something... */
}
应该适用于常规文件和文件夹。
另一答案
我建议你使用SimpleFileVistor类而不是编写代码来遍历目录。
Files类中已经内置了方法来遍历目录。
Files.walkFileTree(path, MyFileVisitor)
您可以创建一个客户访问者类
public class MyFileVisitor extends SimpleFileVisitor<Path>{
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
System.out.println("Visit the File")
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc)
throws IOException {
System.out.println("File Visit Failed")
return FileVisitResult.CONTINUE;
}
}
这可以提高代码的可读性,而且不那么冗长。
以上是关于检查目录及其内容是否已锁定的最佳方法是什么?的主要内容,如果未能解决你的问题,请参考以下文章