2012-12-11 50 views
7

我有eclipse插件jface應用程序。 線程通過BufferedWriter寫入文件。 寫入完成後,我關閉緩衝區,然後嘗試重命名文件。File.renameTo()失敗

但有時文件不會重命名!

我試圖在幾次重試之間添加一些Thread.Sleep(BIG_NUMBER),這沒有幫助。

它看起來像獲得某種鎖定的文件。 (當我殺死jvm我可以重命名文件)。

有什麼我可以做的嗎?

操作系統:Windows XP,Windows 7的 JAVA版本:1.5

+0

您正在運行哪個操作系統? – NPE

+0

你可以發佈你使用的代碼嗎? –

回答

13

File.RenameTo()是依賴於平臺和依託,以成功地重命名文件,以滿足一些條件,更好的方法是使用

Path source = currentFile.toPath(); 
try { 
    Files.move(source, source.resolveSibling(formattedName)); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 

閱讀全文here

從的javadoc:

這種方法的行爲的許多方面是天生 平臺依賴性:重命名操作可能無法從一個文件系統移動 文件到另一個,它可能不是原子的,如果目標抽象路徑名爲 的文件已存在,則它可能不會成功。應始終檢查返回值以確保 重命名操作成功。

請注意,Files類定義move方法以獨立於平臺的方式移動或重命名文件。

+5

不能使用! Java 1.5 – yuris

+0

在我的Windows 7上工作起來就像一個魅力 - 特別是添加REPLACE_EXISTING選項時,以及可選的ATOMIC_MOVE選項。謝謝。 –

0

要使File.renameTo()正常工作,該文件需要以某種方式由外部應用程序寫入。

0

你也可以做類似如下:

File o=new File("oldFile.txt"); 
File n=new File("newFile.txt"); 
n.delete(); 
o.renameTo(n); 

n.delete():我們需要刪除的文件(new.txt)是否存在。

o.rename(n):使該文件(old.txt)更名爲new.txt

How to find out why renameTo() failed?

Reliable File.renameTo() alternative on Windows?

http://www.bigsoft.co.uk/blog/index.php/2010/02/02/file-renameto-always-fails-on-windows

+0

我會盡量使用刪除,但如果刪除失敗(如果文件被鎖定,我將無法刪除它)呢? – yuris

0

我們有問題,在Windows 7下使用UAC和意外的文件權限。 File#canWrite將返回true,即使執行文件I/O的任何嘗試都將失敗。

  1. 確保您要重命名的文件存在
  2. 確保位置您正試圖寫入文件(或重命名文件)進行訪問。我們寫一個簡單的文本文件到這個位置,在我們嘗試任何進一步的I/O之前,檢查它是否存在,並且它的內容是否正確(我們是偏執狂)。
+0

這兩個條件都得到滿足。 – yuris

+0

順便說一句,canwrite返回true – yuris

+0

*「即使執行文件I/O的任何嘗試都會失敗,文件#canWrite將返回'true'」* - 我們在Windows 7下預測到了'File#canWrite'無法檢測到的情況UAC限制,因此將該方法返回爲「true」,任何在指定位置執行文件I/O的嘗試都將失敗(通常是靜默) – MadProgrammer

0

這對我來說工作得很好。重命名使用兩個步驟完成,但不要忘記在manifest.xml中設置權限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" /> 

public boolean RenameFile(String from, String to) { 
    to.replace(" ", ""); // clear all spaces within file name 
    File oldfile = new File(from); 
    File newfile = new File(to); 
    File tempfile = new File(to + ".tmp"); // add extension .tmp 
    oldfile.renameTo(tempfile); 
    return (tempfile.renameTo(newfile)); 
}