2011-08-09 5 views
9

나는 이것이 아주 사소한 일이라고 생각했지만 두통이 컸다. 독점적 인 액세스 권한이 있는지 확인하고 특정 조건을 테스트 한 다음 삭제하는 파일을 열고 싶습니다.삭제를 위해 파일을 올바르게 열려면 어떻게해야합니까?

FileStream s = null; 
try { 
    s = new FileStream (
     path, 
     FileMode.Open, 
     FileAccess.ReadWrite, 
     FileShare.None); 
    // some stuff about the file is checked here 
    s.Dispose(); 
    // hope the file is not accessed by someone else... 
    File.Delete (path); 
    return true; 
} 
catch (IOException) { 
    if (s !=null) s.Dispose(); 
    return false; 
} 

이 일반적으로 작동하지만, 나는 인연의 조건을 피하는 더 나은 방법이있을 거라고 생각 :

는 지금은 99 % 접근 방식을 사용하고 있습니다.

DeleteOnClose 플래그가있는 파일을 여는 것은 삭제 플래그가 이미 설정된 상태에서 열리는 이후에 발생하는 검사가 파일을 삭제하면 안됨을 나타낼 수 있기 때문에 작동하지 않습니다.

+0

이 코드가 도움이 될지 모르지만 codeplex의 [트랜잭션 파일 관리자] (http://transactionalfilemgr.codeplex.com/) 프로젝트를 살펴 보았습니까? – Oded

+3

FileShare.Delete를 사용하여 파일을 열어 스트림을 처리하기 전에 File.Delete를 호출 해 보았습니까? – Fox32

+0

실제로 문제가 무엇입니까? File.Delete와 같은 방법으로 파일이 이미 잠겨 있거나 (다른 사람이 파일을 삭제 한 경우) 첫 번째 열은 IOException을 throw 할 수 있습니다. 당신은 예외를 잡아서 다루므로이 문제로 어디서 문제가 생깁니 까? – Eddy

답변

7

뭔가 :

using (FileStream file = new FileStream(path, 
     FileMode.Open, 
     FileAccess.ReadWrite, 
     FileShare.Delete)) 
    { 
     // you can read the file here and check your stuff 
     File.Delete(path); 
    } 

PS는 다음 '사용'키워드를 확인합니다. Dispose 호출을 처리 할 때 코드를보다 깨끗하게 작성할 수 있습니다.

+0

댓글에 따라 다른 앱이 파일에 액세스하는 것을 허용하지 않습니까? – mafu

+1

@mafutrct - FileShare.Delete는 "후속 파일 삭제 허용"을 의미합니다. 다른 앱에서 삭제할 수는 있지만 쓸 수는없고 읽을 수도 없습니다. –

+0

내 경우에는 파일을 삭제해도 문제가되지 않습니다. 오히려 파일을 쓰는 것 - 나는 그것을 위해 다른 Q를 세울 것이다. – mafu

1

우선 "사용하는"문장을 모방하고 있으며 잘못하고있는 것입니다. finally 절에서는 파일 스트림을 한 번만 삭제해야하며 try 및 catch에서는 두 번 삭제하면 안됩니다. 그러나, 사용하는 것이 더 좋습니다. 당신이 필요로하는, 그래서 만약 NTFS 및 Windows Vista +로 제한하지만 트랜잭션 NTFS는 다음과 같습니다

using (FileStream s = new FileStream()) 
{ 
} 

둘째, 당신이있어 최선의 선택은 트랜잭션 NTFS (https://dev.triflesoft.org/mercurial/nabu/를 래퍼 중 하나가 나부 도서관에서 찾을 수 있습니다)입니다 FAT16/FAT32 또는 Windows XP의 경우이 방법이 아닙니다.


또한 이동/다른 프로세스의 액세스를 허용하는 열린 파일 이름을 바꿀 수 있지만, 이것은 AFAIR 너무 NTFS로 제한됩니다.


파일을 즉시 삭제할 필요가없는 경우 Setup API의 SetupQueueDelete 기능을 사용할 수 있습니다. 이 같은

+0

처분 열려있는 파일을 삭제할 수 없으므로 try 내에서 필요합니다. – mafu

+0

@mafutrct는 dispose 대신 close를 사용합니다. –

+0

@ScottChamberlain : 나는 그것이 어떻게 도움이되는지 이해하지 못합니다. FileStream과 동일한 코드로 맵을 닫고 처리하지 마십시오. – mafu

0

경쟁 조건의 가능성을 완전히 방지 할 수는 없습니다. 수정됩니다 체크 사이와 파일을 삭제하면 프로그램에 문제가있는 점을 감안하면이 적어도 2 해결 방법은 내가 볼 수 있습니다 :

  • 는 임시 파일 이름을 가져옵니다의 임시 파일에 파일의 이름을 변경, 확인을 필요한 경우 다시 이름을 바꿉니다 (비즈니스 논리에 따라 새로운 문제가 발생할 수 있음)
  • 파일을 검사하기 전에 readonly 특성을 설정할 수 있습니다.
관련 문제