2009-03-16 5 views
7

상위 폴더의 후속 삭제/이름 변경을 허용하는 방식으로 파일을 열 수 있습니까?(정말로) 잠그지 않고 파일을 엽니 다?

나는이 작업을 수행 할 수있어 : 파일 핸들이 닫힐 때 파일 수

File.Open("foo.bar", FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete) 

가 삭제 될 수 있습니다. 그러나 오류없이 상위 폴더를 삭제할 수없는 경우

프레임 워크에서 아무것도 찾을 수 없습니다. 간과 한 것이 있거나 상호 작용할 수있는 기본 API가 있습니까?

참고 : 삭제 된 파일의 스트림을 사용할 때 예외가 발생해도 상관하지 않습니다. 사실 그것이 이상적 일 것입니다.

는 UPDATE :

그래서 가장 유망한 생각하지만 난 그냥 작동하지 수 있으며, Hardlink이었다. 부모 디렉터리를 삭제하려고하면 Access Denied로 끝납니다. 여기 내 코드는 다음과 같습니다.

class Program 
{ 
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
    static extern bool CreateHardLink(string lpFileName, string lpExistingFileName, IntPtr lpSecurityAttributes); 

    static void Main(string[] args) 
    { 
     string hardLinkPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); 
     string realPath = @"C:\foo\bar.txt"; 
     if (CreateHardLink(hardLinkPath, realPath, IntPtr.Zero)) 
     { 
      using (FileStream stream = File.Open(hardLinkPath, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.ReadWrite)) 
      { 
       Console.Write("File locked"); 
       Console.ReadLine(); 
      } 

      File.Delete(hardLinkPath); 
     } 
     else 
      Console.WriteLine("LastError:{0}", Marshal.GetLastWin32Error()); 
    } 
} 

답변

0

가장 좋은 해결책은 파일을 임시 스크래치 위치로 복사하는 것입니다. 그런 다음 임시 파일을 열고 끝나면 삭제하십시오.

+0

내가하는 것처럼 들립니다. 파일이 충분히 작 으면 메모리에 복사 할 수 있습니까? – strager

+0

예, 우리는 지금 그 일을하고 있습니다. 그러나 많은 파일들이 있습니다. 그리고 그들은 3Mb에서 100Mb 정도로 상당히 큽니다. 그것은 많은 GC 스 래싱을 야기합니다. –

0

FileOpen은 Kernel32.dll에서 CreateFile을 사용합니다. transaction으로 수행하지 않는 한 모든 옵션이 이미 있으므로 .NET 프레임 워크가 제공하는 것 이상을 달성 할 수 있을지 확신하지 못합니다.

+0

지금 문서를 통해 낚시하고 있습니다. CreateFileTransacted로 열린 파일이 부모 폴더를 삭제할 수 있는지 또는 옵션으로 제안했는지 알고 있습니까? –

+0

파일에 작업중인 스레드가 2 개 있다고 가정합니다. 하나는 열려 있고 다른 하나는 동시에 삭제하려고합니까? –

+0

궁극적으로, 그러나 나는 그들 중 하나만 제어합니다. –

1

NTFS로 작업하는 경우 임시 위치에있는 파일에 대한 다른 하드 링크를 만들 수 있습니다. 파일 복사 오버 헤드를 피할 수 있으며 첫 번째 링크는 여전히 삭제 가능해야합니다 (파일 자체 또는 포함 디렉토리).

+0

흠, 이것은 매우 유망한 것처럼 보이지만 부모 폴더를 삭제하면 여전히 오류가 발생합니다. 어쩌면 내가 뭔가 잘못하고있는 것 같아. 너 스스로 해봤 니? –

+0

하드 링크는 원본 파일과 동일해야합니다. 즉, 실제로 파일에 대한 "기본"포인터 개념이 없으며 모두 동일하게 작동합니다. (다른 디렉토리 포인터를 추가합니다.) 개인적으로이 정확한 상황에서 사용하지는 않았지만 작동해야합니다 ... – Eric

+0

내가 추가 한 코드를 참조하십시오.이 경우가 아닌 것으로 보입니다. –

관련 문제