2011-04-18 4 views
11

일반적으로 작동하지만 사용자 사이트에서 계속 실패하는 MoveFile 메서드가 있습니다.File.Delete가 앞에 오면 File.Move가 실패합니다.

if (File.Exists(target)) 
{ 
    File.Delete(target); 
} 

File.Move(source, target); 

File.Move에 대한 호출은 우리가 그 메소드에 호출을 둘러싼 오류 처리를

System.IO.IOException: Cannot create a file when that file already exists. 

    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) 
    at System.IO.__Error.WinIOError() 
    at System.IO.File.Move(String sourceFileName, String destFileName) 

반복적으로 실패하지만, 우리는 왜 작동하지 File.Delete 알아낼되지 않고 있습니다 아무것도 던지고있어.

파일 사용 권한에 대한 내용은 있지만 File.DeleteUnauthorizedAccessException입니다.

File.Move이 특정 파일을 삭제하기 전에 "파일이 이미 있습니다"와 함께 실패하게 만드는 다른 이유가 있습니까?

+0

호기심 : 비슷한 if (File.Exists (..))에서 File.Move를 래핑하면 어떻게됩니까? – razlebe

+1

삭제 후에 이동이 실패 할 수있는 이유 중 하나는 시스템의 일부 프로세스 (예 : 안티 바이러스 스캐너 또는 검색 인덱서)에서 파일 핸들이 여전히 열릴 수 있다는 것입니다. File.Delete 주석 섹션에서는 "Windows NT 4.0 플랫폼 참고 : 삭제는 일반 I/O 또는 메모리 매핑 된 파일을 삭제하지 않습니다."라는 메시지를 표시하므로 대신 삭제로 표시하고 추가로 호출하면됩니다. 액세스가 거부되었습니다. – kiran

답변

11

논리를 뒤집을 수 있습니까?

File.Copy (source, target, true) 

File.Delete(source) 
+0

좋은 생각 :) +1 –

+0

좋아,이 테스트를 거쳤으며 작동합니다. 답변을 수락하는 데 시간이 걸려서 죄송합니다. 고객 사이트에 응용 프로그램을 배포하기 위해 TeamViewer 액세스에 의존하는 경우 이와 같은 것을 테스트하기가 쉽지 않습니다. –

+0

나는 그 느낌을 안다! 파일이 클 경우에는 단점이 있다는 것을 지적해야합니다 (원본과 대상이 같은 디스크에 있으면 파일 이동이 매우 빠르지 만 데이터 복사는 잠재적으로 취할 것입니다). 언젠가는. 그러나 작은 파일에서는 속도 차이가 미미합니다. – MarcE

4

이전에는 시스템이 프로그램이 실행되는 것보다 "느린"파일을 삭제하는 경향이 있음을 발견했습니다.

이상적으로 파일을 삭제하기 전에 파일을 삭제해야하는지 확인해야합니다. 일반적으로 간단한 Thread.Sleep (200) 또는 이와 유사한 방법으로이 라운드를 수행 할 수 있지만 가장 신뢰할 수있는 방법은 아닙니다.

+1

약간 더 신뢰할 수있는 방법은 파일의 존재를 'Thread.Sleep'으로 루프에서 폴링하고 특정 최대 시간 초과까지 삭제되기를 기다리는 것입니다. – devios1

+0

피할 수없는 경쟁 조건입니다. 반복적으로 다시 시도하는 것이 유일한 방법입니다. – Tergiver

+2

아마도 Thread.Sleep 대신 FileSystemWatcher를 사용 하시겠습니까? – razlebe

4

누군가 다른 사람이 FileShare.Delete 옵션으로 파일을 열면 (삭제 허용)이 문제가 발생할 수 있다고 생각합니다. 이 경우 파일은 삭제 표시되지만 다른 핸들이 닫힐 때까지 실제로 삭제되지는 않습니다.

이러한 프로세스로 어떤 프로세스가 파일을 열 수 있는지 잘 모르겠습니다. 바이러스 백신 소프트웨어가 하나의 가능성 일 수 있습니다.

3

나는 당신이에서 더 나은 결과를 얻을 수 있습니다 생각 :

System.IO.File.Copy(sourceFileName, destFileName, overwrite); 

는 별도로 삭제와 걱정보다는 존재하는 경우 overwrite = true

이 이전 파일을 덮어 쓰게됩니다 있도록.

그런 다음 필요에 따라 원본을 삭제할 수 있습니다.

0

여기 삭제 ---
이의 우리가 File_A 및 File_B을 가정 해 봅시다 복사 또는 폴링을 피할 수 더 나은 방법 목표를 덮어 쓸 수 있습니다. File_B를 File_A 위로 이동하려고합니다.
단계 :
1) File_A의 이름을 File_C의 세 번째 이름 인 File_C로 바꿉니다.
2) File_C를 삭제하십시오.
3) File_B의 이름을 File_A로 바꿉니다.

File.Move("File_A", "File_C"); 
File.Delete("File_C"); 
File.Move("File_B", "File_A"); 

이 원본 파일은 새 파일이 원본 파일을 이동하는 동안 주위에 컴퓨터가 삭제되는 경쟁 조건을 제거합니다.

관련 문제