溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

如何解決java.io.File的renameTo方法移動(dòng)文件失敗的問(wèn)題

發(fā)布時(shí)間:2021-07-07 17:28:44 來(lái)源:億速云 閱讀:554 作者:chen 欄目:開(kāi)發(fā)技術(shù)

本篇內(nèi)容主要講解“如何解決java.io.File的renameTo方法移動(dòng)文件失敗的問(wèn)題”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“如何解決java.io.File的renameTo方法移動(dòng)文件失敗的問(wèn)題”吧!

今天線(xiàn)上發(fā)現(xiàn)一個(gè)問(wèn)題,發(fā)現(xiàn)一個(gè)定時(shí)移動(dòng)文件的業(yè)務(wù)沒(méi)有正常執(zhí)行,結(jié)合日志和代碼發(fā)現(xiàn),移動(dòng)文件是使用File類(lèi)的renameTo方法,但是方法返回的都是false,表示文件移動(dòng)失敗。

出現(xiàn)這個(gè)問(wèn)題我第一反應(yīng)是不是文件權(quán)限的問(wèn)題,但是和運(yùn)維研究后發(fā)現(xiàn)的確不是權(quán)限導(dǎo)致的。既然不是權(quán)限的問(wèn)題,那就看看renameTo的實(shí)現(xiàn)吧,查看源碼發(fā)現(xiàn)該方法最終是通過(guò)一個(gè)本地方法實(shí)現(xiàn)的,看不到咋寫(xiě)的。

網(wǎng)上查了一下renameTo這個(gè)方法,發(fā)現(xiàn)這個(gè)方法確實(shí)存在一些問(wèn)題,就是在不同的文件系統(tǒng)中移動(dòng)是不會(huì)成功的。因?yàn)闇y(cè)試環(huán)境并未出現(xiàn)這個(gè)問(wèn)題,我就把生產(chǎn)環(huán)境和測(cè)試環(huán)境對(duì)比了下,發(fā)現(xiàn)測(cè)試環(huán)境下,文件本身的目錄和要移動(dòng)到的目錄是在/home下,而生產(chǎn)環(huán)境中,文件本身目錄是在/home下,要移動(dòng)到的目錄都是在/data下。于是用df命令查看了一下,發(fā)現(xiàn) /home的文件系統(tǒng)是/dev/sda3,類(lèi)型是xfs的,/data的文件系統(tǒng)是/dev/sdb1,類(lèi)型是ext4。

既然是這樣那就寫(xiě)個(gè)demo在自己的虛擬機(jī)上驗(yàn)證一下是不是這個(gè)原因?qū)е碌摹?/p>

1.首先找兩個(gè)文件系統(tǒng)不一樣的目錄,命令df -T

如何解決java.io.File的renameTo方法移動(dòng)文件失敗的問(wèn)題

我們用/tmp 和 /run 作為測(cè)試目錄。

2.測(cè)試代碼

import java.io.File;
/**
* 文件移動(dòng)方法測(cè)試
*/
public class FileTest {
  public static void main(String[] args) {
     String filePath="/tmp/test.txt";
     File file = new File(filePath);
     boolean b = file.renameTo(new File("/run/test.txt"));
     System.out.println(b);
 }
}

3.編譯運(yùn)行

javac FileTest.java
java FileTest

運(yùn)行結(jié)果輸出false,文件也確實(shí)未移動(dòng)成功

如何解決java.io.File的renameTo方法移動(dòng)文件失敗的問(wèn)題

解決方法:

使用apache的commons-io包中的工具類(lèi)的進(jìn)行文件移動(dòng)。

1.測(cè)試代碼:

import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
/**
* 文件移動(dòng)方法測(cè)試
*/
public class FileTest {
  public static void main(String[] args) {
     String filePath="/tmp/test.txt";
     File file = new File(filePath);
     boolean b = file.renameTo(new File("/run/test.txt"));
     System.out.println(b);
     //使用apache的FileUtils工具
     try {
         FileUtils.moveFile(file,new File("/run/test.txt"));
         System.out.println("success");
     } catch (IOException e) {
         e.printStackTrace();
     }
 }
}

2.編譯運(yùn)行

javac -cp /root/jar/commons-io-2.4.jar FileTest.java
java -cp /root/jar/commons-io-2.4.jar: FileTest

運(yùn)行結(jié)果成功移動(dòng)文件

3.apache的FileUtils移動(dòng)文件方法的主要實(shí)現(xiàn)如下:

//先使用renameTo方法進(jìn)行移動(dòng)
boolean rename = srcFile.renameTo(destFile);
if (!rename) {
 //renameTo移動(dòng)失敗,就復(fù)制文件,然后刪除原文件
 copyFile( srcFile, destFile );
 if (!srcFile.delete()) {
 FileUtils.deleteQuietly(destFile);
 throw new IOException("Failed to delete original file '" + srcFile +
  "' after copy to '" + destFile + "'");
 }
}

總結(jié):

1、文件移動(dòng)最好不要使用Java的renameTo方法,而是應(yīng)該使用apache的commons-io包,當(dāng)然也可以自己封裝類(lèi)似的方法。

2、renameTo方法移動(dòng)失敗是文件系統(tǒng)不同造成的,補(bǔ)充測(cè)試發(fā)現(xiàn)不同的文件系統(tǒng),就算類(lèi)型相同,移動(dòng)也會(huì)失敗。

到此,相信大家對(duì)“如何解決java.io.File的renameTo方法移動(dòng)文件失敗的問(wèn)題”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢(xún),關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI