代码之家  ›  专栏  ›  技术社区  ›  Sharku

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

  •  1
  • Sharku  · 技术社区  · 7 年前

    假设我将一个包含目录路径的字符串传递给一个随机方法。在这个方法开始工作之前,它应该检查目录或它的任何内容是否被锁定。我以为这将是一个简单的任务,但结果我得到了一些几乎不简单的代码来做它。你有什么建议如何改进它或者至少缩短它?

    如果你认为这已经是最好的解决方案,那就放弃投票,继续解决真正的问题: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;
            }
        }
    
    }
    
    3 回复  |  直到 7 年前
        1
  •  1
  •   DavidW    7 年前

    我觉得检查目录中的每个文件都很慢,而且容易出现争用情况。在您的示例中,您会立即获得目录中的文件列表,然后对每个文件进行测试;与此同时,creator线程可能仍在添加文件。即使列表中的每个文件都可以访问,创建者也可能无法完成目录的编写。

    在第一种情况下:

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

    在这两种情况下,creator任务都会在创建完目录后显式地发出信号。如果您只是等待操作暂停,那么它可能只是在等待通过网络加载一个大的缓冲区。

        2
  •  1
  •   Shrawan Kumar    7 年前

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

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

        3
  •  0
  •   codemusings    7 年前

    Files 类及其应用 is* 方法如 isReadable isWritable

    if (Files.isReadable(new File(filepath).toPath()) &&
        Files.isWritable(new File(filepath).toPath()))
    {
        /* do something... */
    }
    

    应该适用于常规文件和文件夹。