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

一直以為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的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值