以前我一直以为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? falserename to e:\test.txt=> falsesource file is exist? true, source file =>c:\test.txt

d:\test.txt is exist? falserename 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的

在大压力情况下在windows renameTo有一定概率失败的情况。

在linux操作系统上在不同盘符之间renameTo也会失败。典型的应用场景就是从本地硬盘renameTo到mount的硬盘上或文件系统上。

copy文件尽量使用FileUtilsc.opyFileToDirectory(File,File)

还有个问题是在使用webwork的fileUpload拦截器的时候尽量不要使用execAndWait拦截器,两个拦截器会开启两个线程,很可能会删掉还没有处理的临时上传文件文件而导致文件找不到。

http://xiaoych.iteye.com/blog/149328

java renameto_请慎用java的File#renameTo(File)方法(转)相关推荐

  1. java的File.renameTo(File)方法

    亲测可用,若有疑问请私信 以前我一直以为File#renameTo(File)方法与OS下面的 move/mv 命令是相同的,可以达到改名.移动文件的目的.不过后来经常发现问题:File#rename ...

  2. JAVA——File.renameTo方法,需要注意的坑

    最近在接手老项目的时候,遇到File.renameTo(File file)方法,不清楚特性,于是研究了下源码,发现底层调用的是Native方法实现的.本身带着对其用法的困惑,写了一个测试用例来揭开它 ...

  3. java file rename 失败_java File renameTo 踩坑---windows vs linux

    Java File renameTo 方法 Windows Linux 下的差异: window : 1 在关闭源文件之前,进行重命名操作,返回 false,重命名失败: 2 目标文件存在时,返回fa ...

  4. Java renameto无效,java – File.renameTo()失败

    File.RenameTo()依赖于平台,并且依赖于要满足的几个条件才能成功重命名文件,更好的选择是使用 Path source = currentFile.toPath(); try { Files ...

  5. Java File renameTo 方法实现文件移动

    renameTo方法:一个文件移到另一个文件下 /** * 移动文件 originalFile:需要移动的文件 targetFile:存放被移动文件的文件夹 */ public static void ...

  6. Java IO流学习总结三十一:File

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/54581478 Java File类的功能非常强大,利用java基本上可以对文件进行 ...

  7. 【转】Java中File常用的方法汇总

    创建: createNewFile()在指定位置创建一个空文件,成功就返回true,如果已存在就不创建,然后返回false. mkdir() 在指定位置创建一个单级文件夹. mkdirs() 在指定位 ...

  8. Java常用工具类---IP工具类、File文件工具类

    package com.jarvis.base.util; import java.io.IOException; import java.io.InputStreamReader; import j ...

  9. Java I/O系统学习系列一:File和RandomAccessFile

    I/O系统即输入/输出系统,对于一门程序语言来说,创建一个好的输入/输出系统并非易事.因为不仅存在各种I/O源端和想要与之通信的接收端(文件.控制台.网络链接等),而且还需要支持多种不同方式的通信(顺 ...

最新文章

  1. android drawpath大小,Android Path和PathMeasure
  2. Linux下安装Solr
  3. .NET开发Windows服务
  4. 查询进程打开的文件(转)
  5. .net core 装了没生效_王者荣耀:辅助装出现惊天bug?辅助光环对自己无效?
  6. 浅谈Kubernetes Service负载均衡实现机制
  7. scala的stream流
  8. Python中的闭包总结
  9. Google分析用户页面滚动深度分析jQuery插件 - jQuery Scroll Depth
  10. 一个悄然成为世界最流行的操作系统
  11. STC89C51单片机串口程序下载失败总结
  12. Mysql分表,分区的区别和联系
  13. 数码管显示原理——MCU51
  14. 温度转换示例(有每一步代码的解释)
  15. W806/W801/W800多通道ADC同时使用
  16. 电瓶车.20180804
  17. 薄膜微压力传感器阵列
  18. 如何查看Android API文档
  19. HDU2063-过山车[Hopcroft-Carp]二分图匹配
  20. 适合运动的无线蓝牙耳机有哪些,运动无线蓝牙耳机推荐

热门文章

  1. nlp翻译模型可以使用到通用人工智能
  2. Gorm学习(五)进阶:多态关联、关联标签以及事务
  3. 面向对象编程的三大特性
  4. 【MySQL入门到高级之基础篇(参考尚硅谷宋红康老师2022版)】
  5. matlab的时域信号计算,matlab – 计算时域数据的能量
  6. 支持DITA的CCMS、编辑器和工具
  7. Eclipse的介绍和插件使用
  8. 取汉字拼音,取汉字英文首字母
  9. Android应用如何添加自定义铃声
  10. 服务器bios固件和麒麟系统,BIOS和固件有什么区别? | MOS86