2013-01-06 31 views
7

Trong ứng dụng của tôi (ứng dụng winforms C# 4.5) Tôi định kỳ kiểm tra nội dung của một thư mục và lưu trữ các chi tiết của bất kỳ tệp nào được tìm thấy trong cơ sở dữ liệu. Trong thói quen này, tôi tạo một cá thể FileInfo bằng cách sử dụng new FileInfo(path) và tôi đọc các thuộc tính CreationTime, LastWriteTime, LastAccessTime, LengthAttributes. Tôi không bao giờ gọi bất kỳ phương thức nào trên cá thể FileInfo. Những gì tôi muốn biết: là có bất kỳ nguy cơ tham nhũng, khóa hoặc lỗi thời gian chạy nếu một tập tin hiện đang được viết bởi một ứng dụng của bên thứ ba (hoặc trong quá trình được sao chép vào thư mục của Windows) trong khi tôi tạo đối tượng FileInfo hoặc truy cập thuộc tính của nó?Có an toàn để tạo một FileInfo trên một tệp hiện đang được ghi vào không?

Trả lời

11

Có, đây là "an toàn". Điều này được xử lý ở mức rất thấp, trình điều khiển hệ thống tệp. Một tệp trên các hệ thống tệp phổ biến như FAT hoặc NTFS có hai cấu trúc riêng biệt trên đĩa là. Đầu tiên là mục nhập thư mục, nó lưu trữ siêu dữ liệu về tệp. Giống như tên, dấu thời gian, thuộc tính và độ dài. Dữ liệu tệp thực được lưu ở nơi khác, một chuỗi các cụm lưu trữ dữ liệu tệp.

FileInfo chỉ cung cấp cho bạn siêu dữ liệu cho tệp. Dữ liệu tệp nhạy cảm hơn nhiều, có thể thay đổi cao như một quá trình ghi vào tệp. Đáng chú ý là bạn có thể khóa quyền truy cập vào dữ liệu tập tin bằng các tùy chọn FileShare. Nhưng không có cách nào để khóa siêu dữ liệu. Theo đó, bạn luôn có thể lấy FileInfo cho một tệp, bất kể quy trình khác đang làm với tệp là gì.

Tất nhiên, thuộc tính FileInfo thực tế có thể thay đổi trong khi quá trình ghi vào tệp. Chúng được cập nhật lazily, đặc biệt là thuộc tính LastAccessTime. Nếu bạn muốn chắc chắn rằng bạn đã có thông tin chính xác không thể thay đổi thì bạn cần lấy khóa trên tệp. Làm như vậy bằng cách mở tệp bằng FileShare.Read hoặc FileShare.None.Điều này đảm bảo rằng không có quy trình nào khác có thể mở tệp để ghi, miễn là bạn đã mở tệp. Lưu ý rằng rằng có thể dễ dàng ném một IOException, bạn sẽ chỉ nhận được khóa khi không có quá trình nào khác đến trước bạn và mở tệp để ghi.

+0

Cảm ơn rất nhiều vì đã giải thích chi tiết. Hãy cho tôi tự tin rằng mã của tôi là an toàn. Tôi thực hiện kiểm tra độc quyền truy cập độc quyền nếu tôi muốn ghi vào một tệp, bằng FileShare.None, nhưng trong trường hợp cụ thể này, tôi chỉ muốn siêu dữ liệu và bây giờ tôi có thể tự tin đọc nó mà không có khả năng làm hỏng tệp đang được ghi vào. – wwarby

1

Không, chúng không nằm trong ngữ cảnh bạn đang sử dụng.

Từ FileSystemInfo.LastWrite -> MSDN

Lưu ý Phương pháp này có thể trả về một giá trị không chính xác, bởi vì nó sử dụng chức năng bản địa có giá trị có thể không được cập nhật liên tục bởi hệ điều hành.

Nhưng hãy tưởng tượng trong một giây, chúng đã trả về các giá trị mới nhất. Nếu bạn đã tiêu thụ giá trị (phụ thuộc vào thời gian), và các tập tin được ghi đè sau đó, các giá trị truy cập cuối cùng của bạn sẽ trở thành sai/hỏng. Vì vậy, điều này không có ý nghĩa.

0

không có vấn đề thấy MSDN:

http://msdn.microsoft.com/en-us/library/system.io.fileinfo.aspx

Chủ đề An toàn Bất kỳ public static (chung trong Visual Basic) thành viên của loại này là chủ đề an toàn. Bất kỳ thành viên cá thể nào cũng không được bảo đảm là luồng an toàn.

thông báo:

Khi các thuộc tính được lấy ra đầu tiên, FileInfo gọi phương thức Refresh và lưu trữ thông tin về các tập tin. Trong các cuộc gọi tiếp theo, bạn phải gọi Làm mới để nhận bản sao thông tin mới nhất.

+1

nhưng có cuộc đua khi đối tượng tệp liên tục bị sửa đổi. – Tilak

+0

họ xử lý nó ở cấp độ của họ và hứa với bạn rằng miễn là bạn sử dụng phương pháp tĩnh, bạn sẽ nhận được một kết quả an toàn. đây có thể không phải là ** mới nhất ** nhưng dữ liệu sẽ không bị ăn mòn. – Nahum

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