2009-03-26 26 views
15

Tôi muốn mở tệp để đọc ở chế độ độc quyền và nếu tệp đã được mở bởi một số quy trình/chuỗi khác, tôi muốn nhận ngoại lệ. Tôi đã thử các mã sau đây, nhưng không làm việc, ngay cả khi tôi mở foo.txt, tôi vẫn có thể đạt được các tuyên bố Console.WriteLine. Bất kỳ ý tưởng?mở tệp ở chế độ độc quyền trong C#

static void Main(string[] args) 
{ 
    using (Stream iStream = File.Open("c:\\software\\code.txt", FileMode.Open, 
    FileAccess.Read, FileShare.None)) 
    { 
     Console.WriteLine ("I am here"); 
    } 

    return; 
} 
+0

"ngay cả khi tôi đã mở foo.txt" -> cách bạn mở nó? –

+0

Có, Mehrdad. Tôi đã mở nó, sau đó thực hiện chương trình của tôi, vẫn có thể đọc câu lệnh Console.WriteLine. Bất kỳ ý tưởng? – George2

+0

Với notepad? Notepad không khóa tệp khi chạy. Nó đọc tập tin trong bộ nhớ và mở lại nó để viết khi bạn lưu. –

Trả lời

1

tôi sẽ đề nghị sử dụng FileAccess.ReadWrite thành viên vì một số tập tin có thể đã được mở nhưng cho phép bạn truy cập Read vào tệp. Tuy nhiên, tôi sẽ đoán rằng trong điều kiện không đặc biệt, tất cả các tệp mở để truy cập Read/Write sẽ không cho phép mã của bạn đến Write vào tệp. Tất nhiên (như Mehrdad đã giải thích), nếu bạn đang sử dụng một trình soạn thảo như Notepad để mở tập tin như một bài kiểm tra, bạn sẽ không thể hạn chế truy cập vì Notepad không khóa tập tin nào cả.

+0

Cảm ơn Cerebrus, bạn là chính xác và tôi đang sử dụng notepad để mở nó và chạy chương trình của tôi để kiểm tra. Bất kỳ ý tưởng để kiểm tra xem một tập tin được mở hay không (ví dụ, tôi muốn mã của tôi để có thể kiểm tra xem notepad đã mở nó)? – George2

+0

Không, tôi không nghĩ rằng có ... ngoại trừ bằng cách bắt IOException trong mã mà cố gắng để sau đó đọc các tập tin. – Cerebrus

+0

Tình huống của tôi là, một chuỗi là serialization (sử dụng XML serialization) vào tệp, một luồng đọc khác được đọc từ tệp này. Tôi không muốn thread đọc để hoạt động trên tập tin này trong khi serialization XML đang trong quá trình, bất kỳ ý tưởng? – George2

16

Điều bạn đang làm là điều đúng. Có lẽ bạn đang thử nghiệm nó không chính xác. Bạn nên mở nó bằng một chương trình mà khóa tệp khi mở. Notepad sẽ không làm. Bạn có thể chạy đơn đăng ký của mình hai lần để xem:

static void Main(string[] args) 
{ 
    // Make sure test.txt exists before running. Run this app twice to see. 
    File.Open("test.txt", FileMode.Open, FileAccess.Read, FileShare.None); 
    Console.ReadKey(); 
} 
+0

Cảm ơn Mehrdad, anyway để kiểm tra xem một tập tin đã được mở bởi thread/quá trình khác? – George2

+0

Tôi không nghĩ rằng có một cách để tìm hiểu xem một quá trình đã mở một tập tin và đang làm việc trên nó. Về mặt kỹ thuật, tệp không còn mở sau khi notepad tải nó vào bộ nhớ. Tôi nghĩ rằng đây là cách đúng đắn để làm điều đó như notepad hoặc các chương trình khác không thể mở nó một lần nữa (để đọc hoặc lưu) mà là tốt, tôi nghĩ. –

+0

Cảm ơn Mehrdad, tôi đã kiểm tra bạn là chính xác. tình hình của tôi là, một thread là serialization (sử dụng XML serialization) vào tập tin, một thread đọc được đọc từ tập tin này. Tôi không muốn thread đọc để hoạt động trên tập tin này trong khi serialization XML đang trong quá trình, bất kỳ ý tưởng? – George2

2

FileShare.None sẽ chỉ hoạt động nếu một quy trình khác cũng đã mở tệp mà không cho phép chia sẻ tệp này cho lần đọc.

Các chương trình như Notepad và Visual Studio không khóa tệp văn bản.

+0

Thanks Jakob, anyway để kiểm tra xem một tập tin đã được mở bởi thread/quá trình khác? – George2

+0

Hi Jakob, tình hình của tôi là, một thread là serialization (sử dụng XML serialization) vào tập tin, một thread đọc được đọc từ tập tin này. Tôi không muốn thread đọc để hoạt động trên tập tin này trong khi serialization XML đang trong quá trình, bất kỳ ý tưởng? – George2

+0

Bạn đang sắp xếp theo thứ tự như thế nào? Khi tuần tự hóa, bạn phải mở tệp độc quyền (ví dụ: FileAccess.Write và FileShare.None). –

3

Điều bạn đã làm là chính xác.

Nếu bạn cần những gì được tất cả các file đã mở, sau đó là một cách để nhìn thấy bằng cách NtQuerySystemInformation

Bạn có thể nhận ý tưởng từ http://www.codeproject.com/KB/shell/OpenedFileFinder.aspx

mà được tất cả các file mở trong một thư mục .. mà có thể được mở rộng đến một tập tin duy nhất cho dù mở hay không ...

+0

Cảm ơn lakshmanaraj, tình hình của tôi là, một thread là serialization (sử dụng XML serialization) vào tập tin, một thread đọc được đọc từ tập tin này. Tôi không muốn thread đọc để hoạt động trên tập tin này trong khi serialization XML đang trong quá trình, bất kỳ ý tưởng? – George2

+0

Bạn có thể khóa tập tin hoặc thực hiện một mutex bằng cách đặt một semaphore hoạt động – lakshmanaraj

+0

tên tập tin là tùy ý do đó rất khó để khóa. Để biết thêm chi tiết, tôi sao chép các tập tin tùy ý từ máy từ xa sang máy cục bộ bằng cách sử dụng chuỗi ghi, và một luồng đọc sẽ quét thư mục và đọc thông tin cho các tệp mới sắp tới – George2

2

thử nghiệm nó bằng cách viết một chương trình đơn giản chế độ giao diện điều khiển mở ra các tập tin và sau đó chờ đợi:

static void Main(string args[]) 
{ 
    using (FileStream f = File.Open("c:\\software\\code.txt", FileMode.Open, FileAccess.Read, FileShare.None)) 
    { 
     Console.Write("File is open. Press Enter when done."); 
     Console.ReadLine(); 
    } 
} 

Chạy chương trình đó từ dòng lệnh (hoặc một phiên bản khác của Visual Studio), rồi chạy chương trình của bạn. Bằng cách đó, bạn có thể chơi với các giá trị khác nhau cho FileMode và FileShare để đảm bảo rằng chương trình của bạn phản ứng chính xác trong mọi trường hợp.

Và, không, bạn không phải kiểm tra xem tệp có được mở trước không. Mã của bạn nên ném một ngoại lệ nếu tệp đã được mở. Vì vậy, tất cả những gì bạn phải làm là xử lý ngoại lệ đó.

+0

Xin chào Jim, tình huống của tôi là, một chuỗi đang sao chép tệp (bằng phương thức File.Move) và một chuỗi khác được đọc từ tệp. Tôi không muốn các chủ đọc đọc một phần của tập tin trong khi sao chép đang trong quá trình (đây là lý do tại sao tôi muốn có chế độ mở độc quyền), không mã của tôi được đăng giải quyết vấn đề này? – George2

+0

Có, mã của bạn giải quyết được vấn đề đó. Nó sẽ không mở tập tin nếu File.Move đang ở giữa sao chép nó. –

+0

Jim, làm thế nào để tôi biết nếu có (!) Chương trình đang mở nó? Hoặc là notepad hoặc cái gì khác. Hoặc làm thế nào để tôi biết nếu nó đang được sao chép ngay bây giờ? –

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