简体   繁体   English

如果在目标目录中有一个同名的文件(java),我如何制作一个被重命名的移动文件?

[英]How can i make a moving file who gets renamed if in the target directory there is a file whit the same name(java)?

我正在为我的电脑编写一个移动文件程序,要完成它我需要重命名一个移动文件,如果在目标目录中已经有一个同名的文件,我该怎么做?

One could use File.move and use CopyOption s.可以使用File.move并使用CopyOption s。 But it seems more elegant to check the existence of the target.但是检查目标的存在似乎更优雅。

void move(Path source, Path target) throws IOException {
    int fileno = 0;
    while (Files.exist(target)) {
        target = ...
        ++fileno;
    }
    // Files.createDirectories(target.getParent());
    Files.move(source, target);
}

In java the convention is that the target is not a directory (the new parent).在 java 中,约定是目标不是目录(新的父目录)。

It's a programming language;它是一种编程语言; you would program the behaviour you want.你会编程你想要的行为。 There is nothing 'baked in', if that's what you were thinking.如果这就是你的想法,那么没有什么“烤熟”的。

As with most things that could potentially interact with other threads or applications running simultaneously, you don't check-and-act - because other apps or threads could change the situation in between your 'check' and your 'act' - instead, you act-then-check: You just do the thing, and catch exceptions that indicate the thing cannot be done due to failing checks, and act accordingly.与可能与同时运行的其他线程或应用程序交互的大多数事物一样,您不会检查并采取行动 - 因为其他应用程序或线程可能会改变您的“检查”和“行动”之间的情况 - 相反,您act-then-check:你只是做这件事,并捕获表明由于检查失败而无法完成的异常,并采取相应的行动。 In other words, don't do something like:换句话说,不要做类似的事情:

while (file.exists()) file = incrementSomething();
writeTo(file);

That's check-then-act.这就是先检查后行动。 Don't do that.不要那样做。

Instead you'd first just move it, and then catch the exception that indicates that it cannot be moved because the 'target' already exists and you did not specify that overwriting is acceptable.相反,您首先只是移动它,然后捕获指示它无法移动的异常,因为“目标”已经存在并且您没有指定可以接受覆盖。

It's your program, you decide what you want to do when this happens.这是你的程序,你决定当这种情况发生时你想做什么。 Perhaps you want to append (1) to the file name and try again, then (2) , and so on, all the way to (999) and once you get that far, just stop and crash.也许您想将(1)附加到文件名并重试,然后(2) ,依此类推,一直到(999) ,一旦到达那么远,就停止并崩溃。 Or perhaps you want to roll up a random sequence of 6 characters and append that, which is a heck of a lot faster if this 'naming conflict' scenario is likely.或者,也许您想汇总 6 个字符的随机序列并附加它,如果可能出现这种“命名冲突”情况,这会快得多。 That's the joy of programming: Anything's possible, you decide what you want and then you write it just like that.这就是编程的乐趣:一切皆有可能,你决定你想要什么,然后你就这样写。

Let's say you want the (1) thing.假设你想要(1)的东西。 It would look something like:它看起来像:

public void move(Path sourceFile, Path targetDir) throws IOException {
  try {
    Files.move(sourceFile, targetDir.resolve(sourceFile.getFileName()));
  } catch (FileAlreadyExistsException e) {
    String baseName = sourceFile.getFileName().toString();
    int lastDot = baseName.lastIndexOf('.');
    String prefix = lastDot == -1 ? baseName : baseName.substring(0, lastDot);
    String suffix = lastDot == -1 ? "" : baseName.substring(lastDot);
    moveIncremental(sourceFile, targetDir, prefix, suffix, 1);
  }
}

private void moveIncremental(Path sourceFile, Path targetDir, String prefix, String suffix, int counter) throws IOException {

  Path target = targetDir.resolve(prefix + " (" + counter + ")" + suffix);
  try {
    Files.move(sourceFile, target);
  } catch (FileAlreadyExistsException e) {
    if (counter >= 999) throw e; // Give up after 1000 increments.
    moveIncremental(sourceFile, targetDir, prefix, suffix, counter + 1);
  }
}

This code first just tries to move it, and responds to the error of 'no can do;这段代码首先只是尝试移动它,并响应错误'no can do; there is a file already there' and then breaks the file into a prefix and suffix, ie something.txt becomes prefix = "something" suffix = ".txt" and will then call a helper method that tries to move it to something (1).txt , all the way up to 999.已经有一个文件',然后将文件分成前缀和后缀,即something.txt变为prefix = "something" suffix = ".txt"然后将调用一个帮助方法,试图将其移动到something (1).txt ,一直到 999。

It's just one of many ways to do this - as I said, your choice.这只是执行此操作的众多方法之一 - 正如我所说,您的选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM