2009-03-27 17 views
9

Tôi có một ứng dụng mà đôi khi tôi cần phải đọc từ tập tin được ghi vào và kết quả là bị khóa. Như tôi đã hiểu từ questions tôi nên bắt IOException và thử lại cho đến khi tôi có thể đọc.cách chờ đợi tốt nhất cho một filelock để phát hành

Nhưng câu hỏi của tôi là làm thế nào để tôi biết chắc chắn rằng tệp bị khóa và rằng nó không phải là một IOExcetpion xảy ra.

Trả lời

5

Khi bạn mở tệp để đọc.NET nó sẽ tại một số điểm cố gắng tạo ra một tập tin xử lý bằng cách sử dụng chức năng CreateFile API mà đặt error code mà có thể được sử dụng để xem tại sao nó thất bại:

const int ERROR_SHARING_VIOLATION = 32; 
try 
{ 
    using (var stream = new FileStream("test.dat", FileMode.Open, FileAccess.Read, FileShare.Read)) 
    { 
    } 
} 
catch (IOException ex) 
{ 
    if (Marshal.GetLastWin32Error() == ERROR_SHARING_VIOLATION) 
    { 
     Console.WriteLine("The process cannot access the file because it is being used by another process."); 
    } 
} 
+2

Thật không may, bạn không thể chắc chắn rằng lỗi Win32 thực sự gây ra bởi lệnh gọi API CreateFile. Điều này có thể thay đổi trong một phiên bản khác của khung công tác. Để chắc chắn, hãy tự gọi API Win32. –

0

Để đọc dữ liệu bạn có thể làm:

sử dụng (FileStream fs = new FileStream (fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)) {.. ..}

và lưu vào file:

sử dụng (FileStream fs = new file Luồng (tên tệp, FileMode.Append, FileAccess.Write, FileShare.Read | FileShare.Delete)) {...}

Cờ ở cuối các nhà thầu mô tả quá trình khác có thể làm gì với tệp. Nó là tốt, tất nhiên, nếu bạn kiểm soát cả ghi và đọc ...

0

Bạn có thể so sánh với các loại IOException để kiểm tra và xem nếu nó không phải là cái gì khác

Chẳng hạn như

if (ex is FileNotFoundException) 

Bạn có thể muốn tìm kiếm trợ giúp trên System.IO. Rất nhiều ngoại lệ trong lớp đó được kế thừa từ IOException. Ngoài kiểm tra để xem nếu nó là một loại ngoại lệ, bạn có thể phải nhìn vào thông điệp của mô tả hoặc bạn có thể nhìn vào thực hiện một cuộc gọi API Win32 vào shell32.dll. Có thể có một chức năng trong đó để kiểm tra xem tệp có bị khóa hay không.

Ngoài ra, nếu bạn hoàn toàn cần phải chờ đợi, bạn có thể sử dụng vòng lặp, nhưng nếu bạn muốn thực hiện các hành động khác trong khi chờ đợi sử dụng một chuỗi không đồng bộ.

0

Bạn có nghĩa là bạn đều đọc và viết vào tập tin? Hoặc một ứng dụng bên ngoài đang viết cho nó.

Nếu bạn đang đọc và viết thì tôi cho rằng bạn đang thực hiện các chủ đề khác nhau trong trường hợp này hãy xem lớp ReaderWriteLock sẽ thực hiện việc quản lý này cho bạn và cho phép bạn cung cấp thời gian chờ.

http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlock.aspx

Nếu không, tất cả những gì bạn cần làm là mở tệp ở chế độ chỉ đọc. Sau đó, bạn không nên gặp bất kỳ sự cố nào:

fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read)); 
4

Có một cuộc thảo luận hữu ích về google groups mà bạn thực sự nên đọc. Một trong những lựa chọn là gần của darin; tuy nhiên, để đảm bảo bạn có được lỗi win32 đúng, bạn thực sự nên gọi chính API win32 OpenFile() (nếu không, bạn thực sự không biết bạn đang truy xuất lỗi nào).

Cách khác là phân tích cú pháp thông báo lỗi: điều đó sẽ thất bại nếu ứng dụng của bạn chạy trên phiên bản ngôn ngữ khác.

Tùy chọn thứ ba là hack bên trong lớp ngoại lệ với sự phản ánh để tìm ra HRESULT thực tế.

Không có lựa chọn thay thế nào thực sự hấp dẫn: thứ bậc IOException sẽ được hưởng lợi từ một vài lớp con IMHO.