`

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

 
阅读更多
转自:
http://xiaoych.iteye.com/blog/149328

以前我一直以为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:





终于明白咯。

做个实验:


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));



结果:

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是文件和目录路径名的抽象表示形式,所以有可能是目录,千万小心。
分享到:
评论

相关推荐

    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 资源管理器的扩展外壳,可以帮助你快速简便的修改文件名和文件修改时间,可以分别处理文件名和扩展名。

    Quick File Rename 1.2

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

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

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

    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

    plan_in_GitHub365

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

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

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

    FILE_fopen_rename_file_

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

    Better File Rename

    批量重命名 綠色 file rename

    Ben's_File3576422019_hitngm_RenameFile_seldomxyk_

    File Reamer is a small program to allow you to rename multiple files. You may need this program if you need to rename lots of pictures e.g. from a camera

    解决log4j:ERROR Failed to rename代码包

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

Global site tag (gtag.js) - Google Analytics