请慎用java的File#renameTo(File)方法(转)
以前我一直以为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”不一样。究竟怎么不一样呢?还是没有想出来...
后面在一个论坛里面发现了某人关于这个问题的阐述:
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 renameTo有一定概率失败的情况。
在linux操作系统上在不同盘符之间renameTo也会失败。典型的应用场景就是从本地硬盘renameTo到mount的硬盘上或文件系统上。
copy文件尽量使用FileUtilsc.opyFileToDirectory(File,File)
还有个问题是在使用webwork的fileUpload拦截器的时候尽量不要使用execAndWait拦截器,两个拦截器会开启两个线程,很可能会删掉还没有处理的临时上传文件文件而导致文件找不到。
http://xiaoych.iteye.com/blog/149328
请慎用java的File#renameTo(File)方法(转)的更多相关文章
- 请慎用java的File#renameTo(File)方法
转载地址:http://xiaoych.iteye.com/blog/149328 以前我一直以为File#renameTo(File)方法与OS下面的 move/mv 命令是相同的,可以达到改名.移 ...
- 在java中使用 File.renameTo(File)实现重命名.
Here is part of my files: [北京圣思园Java培训教学视频]Java.SE.前9日学习成果测试题(2010年12月2日).rar [北京圣思园Java培训教学视频]Java. ...
- Java中File常用的方法汇总
创建:createNewFile()在指定位置创建一个空文件,成功就返回true,如果已存在就不创建,然后返回false.mkdir() 在指定位置创建一个单级文件夹.mkdirs() 在指定位置创建 ...
- java基础学习日志---File方法分析
package FunDemo; import java.io.File; import java.io.IOException; import java.util.Arrays; public cl ...
- Java编程思想:File类其他方法
import java.io.File; public class Test { public static void main(String[] args) { MakeDirectories.te ...
- 【转】Java中File常用的方法汇总
创建:createNewFile()在指定位置创建一个空文件,成功就返回true,如果已存在就不创建,然后返回false.mkdir() 在指定位置创建一个单级文件夹.mkdirs() 在指定位置创建 ...
- Java中File类的方法详解
File类也是Java中一个比较重要的类,通过他我们可以实现对文件的一系列操作,其内置了很多方法,下面我将按方法的功能分块,逐一讲解: 快速导航 构造方法 常用方法 创建目录 判断 `is...` t ...
- java之io之File类的list()方法过滤目录的使用
java的io的知识中,File类必须掌握.File类是对文件或者文件夹的封装.它本身并不能对所封装的文件进行读写,它封装的只是文件或文件夹的周边知识,比如 大小啦,创建日期啦,路径啦等等. 如果Fi ...
- Java文件操作二:File文件的方法
一.文件的判断方法 判断方法 .boolean canExecute()判断文件是否可执行 .boolean canRead()判断文件是否可读 .boolean canWrite() 判断文件是否可 ...
随机推荐
- sed 工具简介
sed 工具简介sed 可以分析 Standard Input (STDIN) 的数据, 然后将数据经过处理后,再将他输出到 standrad out (STDOUT) 的一个工具. 至于处理呢?可以 ...
- 一天一个类,一点也不累之HashSet
最近忙着一个小项目结题,故没能按时完成[一天一个类,一点也不累],还好项目优秀,算是对自己一点点的安慰和鼓励.~~~ 今天要说的是HashSet 既然是继承自Set,那么就必须有Set的一些属性,比如 ...
- 基于visual Studio2013解决算法导论之008快速排序算法
题目 快速排序 解决代码及点评 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #in ...
- Java Arrays Tutorial (3)
Java Arrays Tutorial (3) Data types have a specific set of values. A byte cannot hold a value larger ...
- ASP.NET中操作SQL数据库
在WebConfig中配置数据库连接字符串,代码如下: <connectionStrings> <add name="ConnectionString&qu ...
- Mac中MacPorts安装和使用
文章转载至http://www.zikercn.com/node/8 星期四, 06/07/2012 - 19:02 - 张慧敏 MacPorts简单介绍 MacPorts,以前叫做DarwinPor ...
- iOS经常使用加密方式(MD5,AES,BASE64)与网络数据安全
演示样例项目下载地址 https://github.com/cerastes/Encryption 1MD5 创建MD5类 #import <Foundation/Foundation.h&g ...
- c语言,内存字节对齐
引用:内存字节对齐 写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果往往都比你声明的变量总长度要大,这是怎么回事呢?讲讲字节对齐吧. /************* ...
- Writing a ServiceMain Function(使用RegisterServiceCtrlHandler函数)
The following global definitions are used in this sample. C++ #define SVCNAME TEXT("SvcName&q ...
- 基于visual Studio2013解决面试题之1310随机数
题目