检查目录及其内容是否已锁定的最佳方法是什么?

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*方法,如isReadableisWritable

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;
    }
}

这可以提高代码的可读性,而且不那么冗长。

以上是关于检查目录及其内容是否已锁定的最佳方法是什么?的主要内容,如果未能解决你的问题,请参考以下文章

单线检查对象及其方法是不是都已定义[重复]

Firebase - 始终检查用户是不是登录的最佳方式?

在 Java 中,检查 Selenium WebDriver 是不是已退出的最佳方法

你怎么知道使用JavaScript是否打开大写锁定?

检查网站每个链接的最佳方法是什么?

什么是检查S3对象是否存在的最佳方法?