2015-12-05 62 views
0

我想複製文件並替換現有文件。問題是,如果該文件正在被另一個程序使用,則會發生AccessDeniedException,並且現有文件被刪除。如果複製失敗,我希望保留現有文件。下面的代碼演示了這個問題。 (注意:另據報道在Java Files.copy replace existing deletes file entirely這個問題,但OP沒有提供一種方式來重現問題。)Java Files.copy在訪問被拒絕時刪除文件

public void copyFile(){ 

    Path workingCopy = null; 

    //Create a plain text file called example-file-error.txt, add some text to the file, and save it in user.home 
    Path path = Paths.get(System.getProperty("user.home"), "example-file-error.txt"); 

    try{ 
     workingCopy = Files.createTempFile(path.getParent(), "temp", ".txt"); 

     //Create a locked file, but the lock is actually created by a separate program 
     FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ); 
     FileLock lock = fileChannel.lock(0, Long.MAX_VALUE, true); 

     Files.copy(workingCopy, path, StandardCopyOption.REPLACE_EXISTING); 

    }catch(Exception ex){ 
     ex.printStackTrace(); 
    }finally{ 
     try{ 
      Files.deleteIfExists(workingCopy); 
     }catch(IOException ex){ 
      ex.printStackTrace(); 
     } 

    } 

} 

有沒有一種方式,如果拷貝沒有保留原來的文件嗎?或者,有沒有辦法在嘗試複製之前等待訪問文件?

回答

0

刪除此行Files.deleteIfExists(workingCopy);從最後並把它放在try子句

public void copyFile() { 
Path workingCopy = null; //Create a plain text file called example-file-error.txt, add some text to the file, and save it in user.home 
Path path = Paths.get(System.getProperty("user.home"), "example-file-error.txt"); 
try{ 
workingCopy = Files.createTempFile(path.getParent(), "temp", ".txt"); //Create a locked file, but the lock is actually created by a separate program 
FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ); 
FileLock lock = fileChannel.lock(0, Long.MAX_VALUE, true); 
Files.copy(workingCopy, path, StandardCopyOption.REPLACE_EXISTING); 
Files.deleteIfExists(workingCopy); 

    }catch(Exception ex) 
{ ex.printStackTrace(); } 
+0

這並不能解決問題。現有文件仍然被刪除,但臨時文件被保留。 – meyerjp3

0

的解決方案是使用Files.move()代替Files.copy()的選項StandardCopyOption結束。 REPLACE_EXISTING和StandardCopyOption.ATOMIC_MOVE。原子移動可防止在發生異常時刪除目標文件。該解決方案適用於Windows 10,但原子移動無法保證適用於所有操作系統。我不確定哪些不允許這個選項。解決方案如下。

public void copyFile(){ 

    Path workingCopy = null; 

    //Create a plain text file called example-file-error.txt, add some text to the file, and save it in user.home 
    Path path = Paths.get(System.getProperty("user.home"), "example-file-error.txt"); 

    try{ 
     workingCopy = Files.createTempFile(path.getParent(), "temp", ".txt"); 

     //Create a locked file, but the lock is actually created by a separate program 
     FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ); 
     FileLock lock = fileChannel.lock(0, Long.MAX_VALUE, true); 

     //This line seems to be the solution to the problem 
     Files.move(workingCopy, path, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE); 

    }catch(IOException ex){ 
     ex.printStackTrace(); 
    }finally{ 
     try{ 
      Files.deleteIfExists(workingCopy); 
     }catch(IOException ex){ 
      ex.printStackTrace(); 
     } 

    } 

}