2011-12-29 2 views
2

아파치 코 몬즈의 FileUtils.deleteDirectory()을 사용하여 재귀 적으로 폴더를 지우고 있으며, 심볼릭 링크를 따라 간 것으로 나타났습니다.심볼릭 링크를 따르지 않고 폴더를 재귀 적으로 삭제하는 방법은 무엇입니까?

심볼릭 링크를 따르지 않고 실제 파일과 폴더 만 삭제할 수있는 대안이 있습니까? 또는 FileUtils를 조정하여이 작업을 수행 할 수 있습니까?

+0

관련 질문 : http://stackoverflow.com/questions/2175673/java-check-symbolic-link-file-existence –

+0

@LukasEder - 음, 그래. 나는 그것을 직접 구현할 것이고, 이미 이런 것이 존재하는지 궁금 할 것입니다. – ripper234

+0

Java에서 IO에 대한 OS 특정 구현을 본 기억이 있지만 어디에서 잊어 버렸습니다 ... 다른 대답을 기다립니다. –

답변

1

전체 문제는 FileUtils.isSymlink()의 apparant 버그에서 비롯된 것으로 보입니다 (방금보고했습니다). 나는 deleteDirectory()에 대한 코드를 붙여, 대신 심볼릭 링크를 확인하기 위해 자바 7의 API를 사용하고, 그것을 작동 복사 :

public static void deleteDirectory(File directory) throws IOException { 
    // See http://stackoverflow.com/questions/8666420/how-to-recursively-delete-a-folder-without-following-symlinks 
    // Copied from http://grepcode.com/file/repo1.maven.org/maven2/commons-io/commons-io/2.1/org/apache/commons/io/FileUtils.java#FileUtils.deleteDirectory%28java.io.File%29 
    if (!directory.exists()) { 
     return; 
    } 

    if (!Files.isSymbolicLink(directory.toPath())) { 
     cleanDirectory(directory); 
    } 

    if (!directory.delete()) { 
     String message = "Unable to delete directory " + directory + "."; 
     throw new IOException(message); 
    } 
} 

private static void cleanDirectory(File directory) throws IOException { 
    // Copied from http://grepcode.com/file/repo1.maven.org/maven2/commons-io/commons-io/2.1/org/apache/commons/io/FileUtils.java#FileUtils.cleanDirectory%28java.io.File%29 
    if (!directory.exists()) { 
     String message = directory + " does not exist"; 
     throw new IllegalArgumentException(message); 
    } 

    if (!directory.isDirectory()) { 
     String message = directory + " is not a directory"; 
     throw new IllegalArgumentException(message); 
    } 

    File[] files = directory.listFiles(); 
    if (files == null) { // null if security restricted 
     throw new IOException("Failed to list contents of " + directory); 
    } 

    IOException exception = null; 
    for (File file : files) { 
     try { 
      forceDelete(file); 
     } catch (IOException ioe) { 
      exception = ioe; 
     } 
    } 

    if (exception != null) { 
     throw exception; 
    } 
} 

private static void forceDelete(File file) throws IOException { 
    if (file.isDirectory()) { 
     deleteDirectory(file); 
    } else { 
     boolean filePresent = file.exists(); 
     if (!file.delete()) { 
      if (!filePresent) { 
       throw new FileNotFoundException("File does not exist: " + file); 
      } 
      String message = 
        "Unable to delete file: " + file; 
      throw new IOException(message); 
     } 
    } 
} 
2

내가 단축 ripper234의 답변을.

/** 
* Recursively deletes `item`, which may be a directory. 
* Symbolic links will be deleted instead of their referents. 
* Returns a boolean indicating whether `item` still exists. 
* http://stackoverflow.com/questions/8666420 
*/ 
public static boolean deleteRecursiveIfExists(File item) { 
    if (!item.exists()) return true; 
    if (!Files.isSymbolicLink(item.toPath()) && item.isDirectory()) { 
     File[] subitems = item.listFiles(); 
     for (File subitem : subitems) 
      if (!deleteRecursiveIfExists(subitem)) return false; 
    } 
    return item.delete(); 
}