因为有一个批量重命名的需求,所以我尝试了一下这个File类的rename方法,一开始没有看方法的介绍。程序运行之后,我的文件都没有了!最后发现,如果不指定文件夹的话,会使用当前路径。
因为偶尔也会碰到处理文件的操作问题,所以就来了解一下Java的文件重命名操作。
前面是一些简单的介绍,也可以直接跳到后面看操作,不过多了解一些总是好的。
File类的rename方法
功能介绍:Renames the file denoted by this abstract pathname. 重命名此抽象路径名表示的文件。
这里要特别注意,它的重命名和我们平常的重命名意思不太一样,我们平时使用电脑重命名文件是对文件名进行重命名,但是这个文件是对文件的路径进行重命名。所以,这里的重命名操作有点类似我们日常的对文件的操作结合:文件剪切+重命名。
Many aspects of the behavior of this method are inherently platform-dependent: The rename operation might not be able to move a file from one filesystem to another, it might not be atomic, and it might not succeed if a file with the destination abstract pathname already exists. The return value should always be checked to make sure that the rename operation was successful.
此方法行为的许多方面本质上依赖于平台:重命名操作可能无法将文件从一个文件系统移动到另一个文件系统,它可能不是原子的,如果目标抽象路径名为的文件已经存在,则可能无法成功。应始终检查返回值以确保重命名操作成功。
public boolean renameTo(File dest) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(path);
security.checkWrite(dest.path);
}
if (dest == null) {
throw new NullPointerException();
}
if (this.isInvalid() || dest.isInvalid()) {
return false;
}
return fs.rename(this, dest);
}
前面是一些处理,对输入参数进行检查。然后使用 FileSystem 对象来执行 rename 方法。由于它是和平台相关的,所以不做太多关注,只要使用就行了。
单一文件重命名
注意:重命名之后文件也会移动的,这个方法不是复制,而是一种类似于移动的操作。
目标文件夹
这里对图片 target.jpg 进行重命名操作。
重命名代码
这里代码写得很繁琐,主要是为了体现这个方法的细节,实际上不用这样写。
public class FileRename {
public static void main(String[] args) throws FileNotFoundException, IOException {
String filepath = "D:/DragonFile/target/complete";
File srcFile = new File(filepath + File.separator + "target.jpg");
File desFile = new File(filepath + File.separator + "rename.jpg");
boolean result = srcFile.renameTo(desFile);
if (result) {
System.out.println("文件重命名成功!/n新文件路径:" + desFile.getAbsolutePath());
System.out.println("原文件是否存在:" + srcFile.exists());
} else {
System.out.println("文件重命名失败!");
}
}
}
执行结果
注意:重命名操作之后文件就已经不存在了。这个方法的重命名不是指文件的命名,而是文件路径的命名。如果重命名之后文件所在文件夹不在当前文件夹,不要感到惊讶!
批量文件过滤+重命名
这个和上面其实也没什么区别,只要使用循环即可达到目的。
目标文件夹
提供多种种格式的文件,将这几种文件进行分类。
文件类型:jpeg、jpg、png、txt、gif
以文件类型名创建文件夹,将相应类型的文件放入文件夹中。
处理代码
public class FileRename {
public static void main(String[] args) throws FileNotFoundException, IOException {
String filepath = "D:/DragonFile/rename";
File srcFile = new File(filepath);
/*使用循环处理
*
* 主要思路:首先对文件进行遍历,获取文件的扩展名,
* 然后使用这个扩展名创建文件夹,然后将该文件重命名到新文件夹下。
* */
for (File file : srcFile.listFiles()) {
String filename = file.getName();
int index = filename.lastIndexOf(".");
String suffix = null;
if (index != -1) { //我这里不处理没有扩展名的文件了。
suffix = filename.substring(index+1);
}
File dir = new File(filepath, suffix);
dir.mkdir();
File desFile = new File(dir, filename);
boolean result = file.renameTo(desFile); //将文件 "重命名" 操作
if (result) {
System.out.println("文件重命名成功!" + desFile.getAbsolutePath());
} else {
System.out.println("文件重命名失败!" + srcFile.getAbsolutePath());
}
}
}
}
注意:这里利用了一个小技巧,如果文件夹已经存在,那么 dir.mkdir()
会返回 false,这不影响后面的操作。
如果追求代码严谨,修改为如下即可。
if (!dir.exists())
dir.mkdir();
执行结果
换一种方法处理,作为参考
使用 Java8 的 Stream 进行处理。
public class FileRename {
public static void main(String[] args) throws FileNotFoundException, IOException {
String filepath = "D:/DragonFile/rename";
File srcFile = new File(filepath);
Stream.of(srcFile.listFiles())
.filter(file->file.getName().contains(".")) //过滤不含扩展名的文件,对于文件命名方式以 "." 结束的不考虑。
.forEach(file->{
FileRename.fileRename(file, filepath);
});
}
static boolean fileRename(File file, String filepath) {
String filename = file.getName();
int index = filename.lastIndexOf(".");
String suffix = filename.substring(index+1);
File dir = new File(filepath, suffix);
if (!dir.exists())
dir.mkdir();
File desFile = new File(dir, filename);
return file.renameTo(desFile); //将文件 "重命名" 操作
}
}
注意
这里不建议提前创建文件夹,因为有时候你根本不知道到底有哪些文件类型,这样程序的适应性更好。