`

请慎用java的File#renameTo(File)方法 & renameTo方法举例

 
阅读更多
以前我一直以为File#renameTo(File)方法与OS下面的 move/mv 命令是相同的,可以达到改名、移动文件的目的。不过后来经常发现问题:File#renameTo(File)方法会返回失败(false),文件没有移动,又查不出原因,再后来干脆弃用该方法,自己实现一个copy方法,问题倒是再也没有出现过。

昨天老板同学又遇到这个问题,File#renameTo(File)方法在windows下面工作的好好的,在linux下偶尔又失灵了。回到家我扫了一遍JDK中File#renameTo(File)方法的源代码,发现它调用的是一个本地的方法(native method),无法再跟踪下去。网上有人说该方法在window下是正常的,在linux下面是不正常的。这个很难说通,SUN不可能搞出这种平台不一致的代码出来啊。

后面在SUN的官方论坛上看到有人提到这个问题“works on windows, don't work on linux”,后面有人回复说是“file systems”不一样。究竟怎么不一样呢?还是没有想出来...

后面在一个论坛里面发现了某人关于这个问题的阐述:

引用
In the Unix'esque O/S's you cannot renameTo() across file systems. This behavior is different than the Unix "mv" command. When crossing file systems mv does a copy and delete which is what you'll have to do if this is the case.

The same thing would happen on Windows if you tried to renameTo a different drive, i.e. C: -> D:


终于明白咯。

做个实验:

Java代码 复制代码 收藏代码
  1.   
  2. File sourceFile = new File("c:/test.txt");   
  3. File targetFile1 = new File("e:/test.txt");   
  4. File targetFile2 = new File("d:/test.txt");   
  5. System.out.println("source file is exist? " + sourceFile.exists()   
  6.     + ", source file => " + sourceFile);   
  7. System.out.println(targetFile1 + " is exist? " + targetFile1.exists());   
  8. System.out.println("rename to " + targetFile1 + " => "  
  9.     + sourceFile.renameTo(targetFile1));   
  10. System.out.println("source file is exist? " + sourceFile.exists()   
  11.     + ", source file => " + sourceFile);   
  12. System.out.println(targetFile2 + " is exist? " + targetFile2.exists());   
  13. System.out.println("rename to " + targetFile2 + " => "  
  14.     + sourceFile.renameTo(targetFile2));  
File sourceFile = new File("c:/test.txt");
File targetFile1 = new File("e:/test.txt");
File targetFile2 = new File("d:/test.txt");
System.out.println("source file is exist? " + sourceFile.exists()
    + ", source file => " + sourceFile);
System.out.println(targetFile1 + " is exist? " + targetFile1.exists());
System.out.println("rename to " + targetFile1 + " => "
    + sourceFile.renameTo(targetFile1));
System.out.println("source file is exist? " + sourceFile.exists()
    + ", source file => " + sourceFile);
System.out.println(targetFile2 + " is exist? " + targetFile2.exists());
System.out.println("rename to " + targetFile2 + " => "
    + sourceFile.renameTo(targetFile2));


结果:

Java代码 复制代码 收藏代码
  1.   
  2. source file is exist? true, source file => c:\test.txt   
  3. e:\test.txt is exist? false  
  4. rename to e:\test.txt => false  
  5. source file is exist? true, source file => c:\test.txt   
  6. d:\test.txt is exist? false  
  7. rename to d:\test.txt => true  
source file is exist? true, source file => c:\test.txt
e:\test.txt is exist? false
rename to e:\test.txt => false
source file is exist? true, source file => c:\test.txt
d:\test.txt is exist? false
rename to d:\test.txt => true



注意看结果,从C盘到E盘失败了,从C盘到D盘成功了。因为我的电脑C、D两个盘是NTFS格式的,而E盘是FAT32格式的。所以从C到E就是上面文章所说的"file systems"不一样。从C到D由于同是NTFS分区,所以不存在这个问题,当然就成功了。

果然是不能把File#renameTo(File)当作move方法使用。

可以考虑使用apache组织的commons-io包里面的FileUtils#copyFile(File,File)和FileUtils#copyFileToDirectory(File,File)方法实现copy的效果。至于删除嘛,我想如果要求不是那么精确,可以调用File#deleteOnExit()方法,在虚拟机终止的时候,删除掉这个目录或文件。

BTW:File是文件和目录路径名的抽象表示形式,所以有可能是目录,千万小心。
&&&& -- M
  File f = new File("d:/Test/name");
  File f2 = new File("d:/name2");
  System.out.println(f.renameTo(f2));
  System.out.println(f.getAbsolutePath());//f仍然指向原来的路径,但此时f原来所指的目录或文件已经不再了
  
  //File f3 = new File("d:/Test/name");
  //System.out.println(f.renameTo(f3));//第二次重命名不行了 ,因为f仍然指向原来的路径
  
  File f3 = new File("d:/name3");
  if(!f.exists()){                              //File对象执行完renameTo后,该对象表示的文件或目录就不存在了,被move了
   System.out.println("f not exists");
  }
  System.out.println(f.renameTo(f3));//false,f所指的文件或目录不存在
  
  System.out.println(f2.renameTo(f));//执行完后,恢复原样
  System.out.println(f2.getAbsolutePath());
分享到:
评论

相关推荐

    请慎用java的File#renameTo(File)方法

    java的file rename方法 ...不过后来经常发现问题:File#renameTo(File)方法会返回失败(false),文件没有移动,又查不出原因,再后来干脆弃用该方法,自己实现一个copy方法,问题倒是再也没有出现过。

    Better File Rename 绿色汉化版

    Better File Rename 5.7 绿色汉化版 Better File Rename 是一款强大易用的文件批量改名软件。内置最全面的重命名选项。 现已支持64位操作系统。 5.7 英文原版更新说明: ① 添加了 PDF 格式的用户手册 ② 在所有...

    Better File Rename 好用的文件重命名工具

    Better File Rename 好用的文件重命名工具

    Better File Rename文件重命名工具

    Better File Rename文件重命名工具,功能强大,各种重命名。 适合文件处理各种使用。

    Better File Rename v5.7

    Better File Rename 是一款WINDOWS 资源管理器的扩展外壳,可以帮助你快速简便的修改文件名和文件修改时间,可以分别处理文件名和扩展名。

    java临时文件重命名-Java程序重命名文件或目录.pdf

    java临时⽂件重命名_Java程序重命名⽂件或⽬录 ⽅法java.io.File.renameTo()⽤于重命名⽂件或⽬录。此⽅法需要⼀个参数,即⽂件或⽬录被重命名的名称,重命名成功后返回true,否则 返回false。 演⽰此的程序如下所⽰...

    Quick File Rename 1.2

    Quick File Rename 批量修改文件后缀,功能简单,但很实用。个人认为比那些体积庞大的工具要好用的多。

    Better File Rename 4.9.4

    是一款WINDOWS资源管理器的扩展外壳,可以帮助你快速简便的修改文件名和文件修改时间,可以分别处理文件名和扩展名。 一款WINDOWS资源管理器的扩展外壳, 可以帮助你快速简便地修改文件名和文件修改时间。...

    FileNameChanger_RenameFile_

    XML file to rename bulk of files

    Delphi RenameFile修改文件名范例.rar

    本例中修改文件名使用Delphi中自带函数RenameFile来实现,具体用法可参考下述代码:  Try  RenameFile(Edit1.Text,Edit2.Text);  SHowMessage('更改成功');  except  ShowMessage('更改失败');  end;

    rename file

    该程序可以成批次的更改文件名称,代码值得学习研究,编译后,即可执行

    file_rename.zip

    python笔记源码,凑字数:请支持我请支持我请支持我请支持我

    rename_file_v1.1.zip

    基于上一个版本修正: 1、正则修正忽略大小写,支持E/EP/Ep/e/ep/eP等 2、支持百集以上电视剧,并自动在单数补0,如100集电视剧,第一集表示为001

    Tag&Rename 3.5.1

    Tag&Rename 3.5.1

    plan_in_GitHub365

    GitHub365计划 此举主要目的是为了复习以前的知识,并对自己的自律进行...RenameMess.java 测试 renameTo 重命名方法 ####2015-1-26 BulbbleSort.java 冒泡排序 ####2015-1-27 duotaiarray-* 多态数组的demo ####2015-

    Better File Rename 个人珍藏 批量文件重命名利器

    本不该要分 但我下载缺分 没办法,大家多支持逸云科技!谢谢 一款WINDOWS资源管理器的扩展外壳, 可以帮助你快速简便地修改文件名和文件修改时间。功能有:强大的命名方式,文字、日期和序列数字的添加、去除、插入和...

    linux下用renameTo方法修改java web项目中文件夹名称的实例

    下面小编就为大家带来一篇linux下用renameTo方法修改java web项目中文件夹名称的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    FILE_fopen_rename_file_

    这是一个打开文件实例,讲述了几个文件函数以及字符串函数的用法,有点乱

    解决log4j:ERROR Failed to rename代码包

    log4j:ERROR Failed to rename错误解决办法 http://www.blogjava.net/DreamAngel/archive/2011/11/10/363400.html

    Better File Rename

    批量重命名 綠色 file rename

Global site tag (gtag.js) - Google Analytics