How to atomically rename a file in Java, even if the dest file already exists?

前端 未结 8 2089
难免孤独
难免孤独 2020-12-09 07:55

I have a cluster of machines, each running a Java app.

These Java apps need to access a unique resource.txt file concurently.

I need to atomical

相关标签:
8条回答
  • 2020-12-09 08:18

    For Java 1.7+, use java.nio.file.Files.move(Path source, Path target, CopyOption... options) with CopyOptions "REPLACE_EXISTING" and "ATOMIC_MOVE".

    See API documentation for more information.

    For example:

    Files.move(src, dst, StandardCopyOption.ATOMIC_MOVE);
    
    0 讨论(0)
  • 2020-12-09 08:23

    I solve with a simple rename function.

    Calling :

    File newPath = new File("...");
    newPath = checkName(newPath);
    Files.copy(file.toPath(), newPath.toPath(), StandardCopyOption.REPLACE_EXISTING);
    

    The checkName function checks if exits. If exits then concat a number between two bracket (1) to the end of the filename. Functions:

    private static File checkName(File newPath) {
        if (Files.exists(newPath.toPath())) {
    
            String extractRegExSubStr = extractRegExSubStr(newPath.getName(), "\\([0-9]+\\)");
            if (extractRegExSubStr != null) {
                extractRegExSubStr = extractRegExSubStr.replaceAll("\\(|\\)", "");
                int parseInt = Integer.parseInt(extractRegExSubStr);
                int parseIntPLus = parseInt + 1;
    
                newPath = new File(newPath.getAbsolutePath().replace("(" + parseInt + ")", "(" + parseIntPLus + ")"));
                return checkName(newPath);
            } else {
                newPath = new File(newPath.getAbsolutePath().replace(".pdf", " (" + 1 + ").pdf"));
                return checkName(newPath);
            }
    
        }
        return newPath;
    
    }
    
    private static String extractRegExSubStr(String row, String patternStr) {
        Pattern pattern = Pattern.compile(patternStr);
        Matcher matcher = pattern.matcher(row);
        if (matcher.find()) {
            return matcher.group(0);
        }
        return null;
    }
    

    EDIT: Its only works for pdf. If you want other please replace the .pdf or create an extension paramter for it. NOTE: If the file contains additional numbers between brackets '(' then it may mess up your file names.

    0 讨论(0)
提交回复
热议问题