慎用java的File#renameTo(File)方法
来源:互联网 发布:mysql 复合主键怎么写 编辑:程序博客网 时间:2024/05/03 17:34
一直以为File#renameTo(File)方法与OS下面的 move/mv 命令是相同的,可以达到改名、移动文件的目的。不过后来经常发现问题:File#renameTo(File)方法会返回失(false),文件没有移动,又查不出原因。
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是文件和目录路径名的抽象表示形式,所以有可能是目录,千万小心。
网友回复:文件系统不一样好像是说 windows和Linux的文件默认为NTFS的 而Linux是ext32的
- 慎用java的File#renameTo(File)方法
- 请慎用java的File的renameTo(File)方法
- 请慎用java的File#renameTo(File)方法
- 请慎用java的File#renameTo(File)方法
- 请慎用java的File#renameTo(File)方法
- 请慎用java的File#renameTo(File)方法
- 请慎用java的File#renameTo(File)方法
- 请慎用java的File#renameTo(File)方法(转)
- 请慎用java的File#renameTo(File)方法
- 请慎用java的File#renameTo(File)方法
- 请慎用java的File#renameTo(File)方法
- 请慎用java的File#renameTo(File)方法
- 请慎用 java 的 File#renameTo(File) 方法
- 请慎用java的File#renameTo(File)方法
- 请慎用java的File#renameTo(File)方法
- 请慎用java的File#renameTo(File)方法
- zz 请慎用java的File#renameTo(File)方法
- 请慎用java的File#renameTo(File)方法
- 开启另一个Activity
- Java获取Mac地址
- kafka.common.ConsumerRebalanceFailedException-org.I0Itec.zkclient.exception.ZkNoNodeException
- PIT工作原理
- <iOS>git-起步
- 慎用java的File#renameTo(File)方法
- thread 源码分析
- Spring:AOP(四)注解方式实现AOP
- iOS自动布局实现Cell和Tableview高度自适应(SDAutoLayout)
- 数据挖掘boosting
- javascript: history.go(-1)和response.redirect();
- 学习笔记_android之选择合适的数据存储方式
- Android中WebView,打开第三方应用的问题
- Portable 433.92-315 jammer Remote control car blocker CTS-UV1A