如何在Java 7中重命名(而不是移动)文件?

22

我对JDK7中所有这些新的文件I/O类有点困惑。

假设我有一个Path并想要重命名它所代表的文件。当再次需要一个Path时,我该如何指定新名称?

Path p = /* path to /home/me/file123 */;
Path name = p.getName(); /* gives me file123 */
name.moveTo(/* what now? */); /* how to rename file123 to file456? */

注:为什么我需要 JDK7?因为要处理符号链接

问题是:我需要处理运行时已知名称和位置的文件。因此,我需要一种安全的方法(不会有异常副作用)来创建一条旧名称路径的新名称路径。

Path newName(Path oldName, String newNameString){
    /* magic */ 
}
6个回答

61
在JDK7中,Files.move()提供一种简短而简洁的语法来重命名文件。
Path newName(Path oldName, String newNameString) {
    return Files.move(oldName, oldName.resolveSibling(newNameString));
}

首先,我们使用Path.resolveSibling()获取新文件名的路径, 然后使用Files.move()来实际更改文件名。


这个有额外的好处,就是它不依赖于平台,而像 moveTo 经常会出现错误。 - Leon

9

您有一个路径字符串,需要创建Path实例。您可以使用getPath方法或resolve方法来完成这个任务。以下是其中一种方式:

Path dir = oldFile.getParent();        
Path fn = oldFile.getFileSystem().getPath(newNameString);
Path target = (dir == null) ? fn : dir.resolve(fn);        
oldFile.moveTo(target); 

请注意它会检查父级是否为空(似乎您的解决方案没有这样做)。

4

好的,在尝试了一切之后,似乎我找到了正确的方法:

// my helper method
Path newName(Path oldFile, String newNameString){
    // the magic is done by Path.resolve(...)
    return oldFile.getParent().resolve(newNameString);
}

// so, renaming is done by:
oldPath.moveTo(newName(oldFile, "newName"));

1

如果你看一下Apache Commons IO,那里有一个叫做FileNameUtils的类。它在文件路径名方面做了很多工作,并且可以(除其他事项外)可靠地拆分路径名等。我认为这应该能让你朝着你想要的方向迈进很长一段路。


抱歉,我需要支持符号链接的API。所有这些Apache Commons的东西最多只能兼容Java 5,但大多数只能兼容Java 1.4。 - java.is.for.desktop
它不仅有助于将文件名拆分和重新组装,而且您还可以使用 Java 7 软链接感知功能来执行复制/重命名操作吗? - Brian Agnew
只有JDK7才提供了处理符号链接的良好功能,因为它具有与操作系统的低级(二进制级别)绑定。 - java.is.for.desktop
很抱歉,在某些情况下,这种分割和重新组装可能会导致错误。但是请等一下,我现在正在尝试使用Path.resolve(String name)。我想那就可以了。 - java.is.for.desktop

0

如果目标路径与源路径相同,仅文件名不同,则文件将被重命名而非移动。

因此,在您的示例中,moveto路径应为

/home/me/file456

1
那我只需要创建一个新的 Path 吗?有比这更简单的方法吗:Path newName = Paths.get(name.getParent().toString()+pathSeparator+"newName");? - java.is.for.desktop
是的,现在的问题是:如何以安全的方式创建这样的路径,以便没有异常情况会导致它失败。 - java.is.for.desktop
我可以尝试描述如何采取原始路径,去掉名称“file123”,改为连接“file456”并调用name.moveTo(),但由于我不太了解Java,所以这只是猜测。我确定的是,如果仅文件名不同,则移动变为重命名 - pavium

-2
如果你无法让Java在Unix上实现你想要的功能,我建议使用Python脚本(由你的Java程序运行)。Python对Unix脚本有很好的支持,而且它不是Perl :) 也许这听起来不太优雅,但在一个更大的程序中,使用正确的工具会让你受益匪浅。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接