2009-03-16 16 views
7

Có thể mở một tệp theo cách cho phép xóa/đổi tên thư mục mẹ sau đó không?Mở tệp mà không (thực sự) khóa nó?

Tôi biết bạn có thể làm điều này:

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

Mà sẽ cho phép các tập tin bị xóa khi tập tin xử lý được đóng lại. Tuy nhiên, nếu nó không cho phép thư mục cha bị xóa mà không có lỗi.

Tôi không thể tìm thấy bất kỳ thứ gì trong khuôn khổ. Tôi đã bỏ qua một cái gì đó, hoặc là có một API bản địa tôi có thể interop đến.

Lưu ý: Tôi không quan tâm nếu tôi có ngoại lệ khi sử dụng luồng của tệp đã xóa. Trong thực tế đó sẽ là lý tưởng.

UPDATE:

Vì vậy, ý tưởng hứa hẹn nhất là Hardlink, tuy nhiên tôi không thể làm cho nó làm việc. Tôi vẫn kết thúc với Truy cập bị từ chối khi tôi cố gắng xóa thư mục mẹ. Đây là mã của tôi:

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()); 
    } 
} 

Trả lời

0

Giải pháp tốt nhất tôi có thể làm là sao chép tệp vào vị trí tạm thời. Sau đó, mở tệp tạm thời và xóa nó khi tôi hoàn tất.

+0

Nghe giống như điều tôi muốn làm. Có lẽ bạn có thể sao chép vào bộ nhớ nếu tệp đủ nhỏ? – strager

+0

vâng, chúng tôi đang làm điều đó ngay bây giờ, nhưng có rất nhiều tập tin, và chúng là khá lớn 3Mb đến 100Mb. Nó gây ra rất nhiều cú đập GC. –

0

FileOpen sử dụng CreateFile trong Kernel32.dll. Tôi không chắc chắn bạn sẽ có thể đạt được bất cứ điều gì nhiều hơn các.NET framework cung cấp cho bạn, như tất cả các tùy chọn đã có, trừ khi bạn thực hiện nó như là một transaction.

+0

Tôi đang câu cá thông qua tài liệu ngay bây giờ. Bạn có biết nếu một tệp được mở bằng CreateFileTransacted, cho phép xóa thư mục mẹ hoặc bạn chỉ đang đề xuất nó như một tùy chọn? –

+0

Tôi giả sử có 2 luồng làm việc trên tệp, một tệp để mở và một chuỗi khác đang cố xóa cùng một lúc? –

+0

Cuối cùng, nhưng tôi chỉ kiểm soát một trong số họ. –

1

Nếu bạn đang làm việc với NTFS, bạn có thể tạo một liên kết cứng khác vào tệp ở một vị trí tạm thời, bạn sẽ tránh được phí sao chép tệp và liên kết đầu tiên vẫn sẽ bị xóa (chính tệp hoặc tệp chứa thư mục) mà không ảnh hưởng đến thư mục thứ hai.

+0

Hmmm, Điều này có vẻ rất hứa hẹn, tuy nhiên tôi vẫn gặp lỗi khi tôi xóa thư mục mẹ. Có lẽ tôi đang làm điều gì sai. Bạn đã thử điều này chưa? –

+0

Các liên kết cứng phải giống hệt với tệp gốc, nghĩa là, không có khái niệm nào về một con trỏ "chính" đến tệp, tất cả chúng đều hoạt động giống nhau. (nó cho biết thêm một con trỏ thư mục khác) Tôi chưa đích thân sử dụng chúng trong tình huống chính xác này, nhưng nó sẽ hoạt động ... – Eric

+0

Xem mã tôi đã thêm vào, điều này có vẻ không đúng. –

Các vấn đề liên quan