재귀 적으로 디렉토리를 삭제하려고 시도하고 탐색기에서 a디렉토리 a\b가 열려 b있으면 삭제되지만 a이동하고 볼 때 디렉토리가 비어 있어도 '디렉토리가 비어 있지 않습니다'라는 오류 가 발생합니다. 모든 응용 프로그램 (탐색기 포함)의 현재 디렉토리는 디렉토리에 대한 핸들을 유지합니다 . 당신이 호출 할 때 Directory.Delete(true), 그것은 아래에서 위로 삭제합니다 b다음 a. b탐색기에서이 열려 있으면 탐색기에서 삭제를 감지하고 b디렉토리를 위쪽으로 변경 cd ..하며 열린 핸들을 정리합니다. 파일 시스템이 비동기 적으로 작동하기 때문에 Directory.Delete탐색기와의 충돌로 인해 작업이 실패합니다.
불완전한 솔루션
필자는 탐색기 스레드가 디렉토리 핸들을 해제 할 수 있도록 현재 스레드를 중단한다는 아이디어와 함께 다음 솔루션을 게시했습니다.
// incomplete!
try
{
Directory.Delete(path, true);
}
catch (IOException)
{
Thread.Sleep(0);
Directory.Delete(path, true);
}
그러나 열린 디렉토리가 삭제하려는 디렉토리 의 바로 하위 인 경우에만 작동합니다 . 경우 a\b\c\d탐색기에서 열려 있고이에를 사용 a,이 기술은 삭제 한 후 실패 d하고 c.
다소 더 나은 솔루션
이 방법은 하위 디렉토리 중 하나가 탐색기에서 열려 있어도 깊은 디렉토리 구조의 삭제를 처리합니다.
/// <summary>
/// Depth-first recursive delete, with handling for descendant
/// directories open in Windows Explorer.
/// </summary>
public static void DeleteDirectory(string path)
{
foreach (string directory in Directory.GetDirectories(path))
{
DeleteDirectory(directory);
}
try
{
Directory.Delete(path, true);
}
catch (IOException)
{
Directory.Delete(path, true);
}
catch (UnauthorizedAccessException)
{
Directory.Delete(path, true);
}
}
우리 자신의 재발의 추가 작업에도 불구하고, 우리는 여전히UnauthorizedAccessException 길을 따라 발생할 수있는 것을 처리해야 합니다. 첫 번째 삭제 시도가 두 번째, 성공한 시도를위한 길을 닦고 있는지 또는 파일 시스템이 따라 올 수있는 예외를 던지거나 잡는 데서 발생하는 타이밍 지연인지는 확실하지 않습니다.
블록 Thread.Sleep(0)의 시작 부분에 a 를 추가하여 일반적인 조건에서 발생하고 포착되는 예외 수를 줄일 수 있습니다 try. 또한 시스템로드가 많은 경우 두 가지 Directory.Delete시도 를 모두 수행 하여 실패 할 수있는 위험이 있습니다. 이 솔루션을보다 강력한 재귀 삭제의 시작점으로 고려하십시오.
일반적인 답변
이 솔루션은 Windows 탐색기와 상호 작용하는 특성 만 해결합니다. 견고한 삭제 작업을 원할 경우, 무엇이든 (바이러스 스캐너 등) 언제라도 삭제하려는 항목에 대해 열린 핸들을 가질 수 있다는 점을 명심해야합니다. 따라서 나중에 다시 시도해야합니다. 나중에 얼마나 많이 시도하고 몇 번 시도하는지는 개체를 삭제하는 것이 얼마나 중요한지에 달려 있습니다. 으로 MSDN을 나타냅니다 ,
강력한 파일 반복 코드는 파일 시스템의 많은 복잡성을 고려해야합니다.
NTFS 참조 문서에 대한 링크 만 제공되는이 무고한 진술은 머리카락을 돋보이게해야합니다.
( 편집 : 많이.이 답변은 원래 첫 번째, 불완전한 솔루션 만 가지고있었습니다.)