2016-09-22 1 views
3

파일을 만들려고하는데 그 전에 파일을 삭제하려고합니다. 내 문제는 내가 성공적으로 삭제 작업을하고 그 직후에 같은 폴더를 만들려고 할 때마다 AccessDenied와 함께 실패합니다. 메서드 설명 (deleteIfExists 및 createDirectory)에 대해 이러한 동작을 언급하지 않으므로 잘못된 작업을 수행하고있는 것 같습니다. 성공적인 실행에성공적인 삭제 직후에 디렉토리를 만들려고 시도합니다 .IfExists가 AccessDenied 예외를 throw합니다.

package nio2; 
import java.io.*; 
import java.nio.file.*; 
public class Test{ 

    public static void main(String[] args) 
    { 
     Path existing = Paths.get("nio2//alpha//inner.txt"); // already existing 
     Path cpytarget = Paths.get("nio2//alphacpy//inner.txt"); // file to be created 
     Path target = Paths.get("nio2//alphacpy");// 
     try{ 
      if(Files.exists(cpytarget)) 
      { 
       Files.list(target).forEach(Test::WrappedDeleteIfExists); // deleting files inside folder 
       System.out.println("Deleting the directory if it exists - alphaCpy\t" + Files.deleteIfExists(target));//deleting 
      } 
      else 
       System.out.println("It does not exist, no need to delete anything"); 
      System.out.println("Creating alphaCpy\t" + Files.createDirectory(target));//creating 
      System.out.println("copying inner.txt to the new directory\t" + Files.copy(existing,cpytarget)); 
     }catch(IOException e) 
     { 
      e.printStackTrace(); 
     } 
    } 
    public static void WrappedDeleteIfExists(Path in) 
    { 
     try{ 
      System.out.println("Deleting files inside the folder\t" + Files.deleteIfExists(in)); 
     }catch (IOException e) 
     { 
      e.printStackTrace(); 
     } 
    } 

} 

그래서 (더 삭제 없음) :

는 코드입니다. 난 그 후 그것을 실행하면이 폴더와 파일이 이미 존재하는 경우 i는 예외가 출력

It does not exist, no need to delete anything 
Creating alphaCpy  nio2\alphacpy 
copying inner.txt to the new directory nio2\alphacpy\inner.txt 

입니다 : 이미 삭제 된 바와 같이

Deleting files inside the folder  true 
Deleting the directory if it exists - alphaCpy true 
java.nio.file.AccessDeniedException: nio2\alphacpy 
     at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:83) 
     at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97) 
     at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102) 
     at sun.nio.fs.WindowsFileSystemProvider.createDirectory(WindowsFileSystemProvider.java:504) 
     at java.nio.file.Files.createDirectory(Files.java:674) 
     at nio2.Test.main(Test.java:19) 

다음 실행 다시 성공 곧. 그렇다면 AccessDenied 예외가 발생하는 이유는 무엇입니까? 파일이 열리거나 사용되지 않으며 상대 경로가 유효하다는 것을 명심하십시오.

편집 : 좋아요. 나는 그것을 수정할 수 있었지만 정직하게는 여전히 초기 문제를 나 자신에게 설명 할 수 없습니다. 누군가가 그 일을 도울 수 있다면 감사 할 것입니다. 나는 Stream을 사용하여 File []을 사용하여 폴더 안의 파일을 삭제했다. 내가 한 후에 그것은 매력처럼 작동합니다. 여기

는 수정 된 코드입니다 :
public static void main(String[] args) throws InterruptedException 
    { 
     Path existing = Paths.get("E:/work/Java/Tests/alpha/inner.txt"); // already existing 
     Path cpytarget = Paths.get("E:/work/Java/Tests/alphacpy/inner.txt"); // file to be created 
     Path target = Paths.get("E:/work/Java/Tests/alphacpy");// 
     File fileTarget = new File("E:/work/Java/Tests/alphacpy");  
     try{ 
      if(Files.exists(cpytarget)) 
      { 
       WrappedDeleteIfExists(fileTarget.listFiles()); // CHANGED , no longer using Stream<Path> pipeline to go through the file list 
       // deleting files inside folder 
       System.out.println("Deleting the directory if it exists - alphaCpy\t" + Files.deleteIfExists(target));//deleting 
      } 
      else 
       System.out.println("It does not exist, no need to delete anything"); 
      System.out.println(Files.exists(target)); 

      System.out.println("Creating alphaCpy\t" + Files.createDirectory(target));//creating 
      System.out.println("copying inner.txt to the new directory\t" + Files.copy(existing,cpytarget)); 
     }catch(IOException e) 
     { 
      e.printStackTrace(); 
     } 
    } 
    // CHANGED - using File[] instead of Path 
    public static void WrappedDeleteIfExists(File[] in) 
    { 
     for(int i =0;i<in.length;i++) 
     { 
      System.out.println("Deleting files inside the folder\t" +in[i].delete()); 
     } 

    } 

은 분명히 스트림 작업조차 마친 후, 어떻게 든 고정 유지되지만, 이것은 IO 스트림 아니다 (또는()의 files.list 함께 ??) 내가 닫을 수있는, 그래서 내가 스트림과 함께 작동하도록 할 수 있습니다 - 그게 아니에요 닫을 수있는 또는 무언가가 GC를 강제하는 것은 의미가 있습니다.

+0

디버거에서 한 번에 한 줄씩 코드를 단계별 실행해도 여전히 같은 오류가 표시됩니까? 그렇지 않은 경우, 운영체제에 의해 삭제가 승인 되 자마자 삭제 연산이 반환 될 수 있지만 OS는 디렉토리의 삭제를 완료하기 위해 유한 한 시간 (수십 밀리 초에서 수백 밀리 초)을 취할 수 있습니다. 이 경우 1 초 정도의 지수 적 백 오프가있는 재시도 루프를 삽입해야합니다. 실제 액세스 거부 상태가있을 수 있으므로 무기한 재 시도 할 수 없습니다. –

+0

단계별로 디버거에서 같은 결과가 나타납니다. 또한 Thread.sleep (5000)을 추가하여 시도했습니다. , 메인 쓰레드가 삭제 된 후 2 초를 기다린다. 결과에 변화가 없습니다. –

+1

왜 이중 _forward_ 슬래시를 사용합니까? 너는 그렇게해서는 안된다. 단일 슬래시를 사용해보십시오. 또한 삭제 작업 후에'Files.exists (target)'의 값을 출력하여 NIO 스택이 디렉토리의 존재에 대해 어떻게 생각하는지 확인하십시오. –

답변

0

Files.deleteIfExists (path) 다음에 Files.list (dir)를 사용하는 프로그램에서 비슷한 문제가 나타났습니다. 삭제 된 폴더는 VM이 ​​종료 될 때까지 Windows 탐색기보기에서 사라지지 않고 Windows 탐색기에서 VM이 종료 될 때까지 클릭하면 액세스가 거부됩니다.

내 프로그램은 사용 후 각 Files.list() 스트림을 닫음으로써 간단하게 해결되었습니다. try (resource) ... finally가 가장 좋습니다. 그런 다음 Windows 탐색기가 각 삭제와 즉시 동기화되어 VM이 종료 될 때까지 기다리지 않습니다.

try(Stream<Path> str = Files.list(target)) 
{ 
    // do your str.forEach() calls with Files.deleteIfExists 
} 
finally 
{ 
} 
관련 문제