2011-09-04 42 views
13

Tôi đang cố gắng sử dụng FSEvents để phát hiện khi tệp được thêm/xóa khỏi thư mục cụ thể. Hiện tại, tôi đã triển khai một trình bao bọc đơn giản xung quanh FSEvents và nó hoạt động tốt: Tôi nhận được tất cả các sự kiện. NHƯNG vấn đề tôi có bây giờ là khi tôi đổi tên một tập tin trong Finder, tôi bắt 2 sự kiện riêng biệt: một sự kiện đầu tiên của loại "đổi tên" với tên tập tin cũ, và một cái khác với "đổi tên" và tên tệp mới. Các id sự kiện khác nhau giữa cả hai cuộc gọi.đổi tên tệp theo dõi/xóa bằng FSEvents trên Lion

Vì vậy, làm cách nào tôi biết được sự kiện "được đổi tên" nào chứa tên cũ và sự kiện nào chứa sự kiện cũ? Tôi đã thử tìm kiếm trong tài liệu, nhưng không may, kFSEventStreamEventFlagItemRenamed không được ghi lại ... có vẻ như mới trong Lion.

PS: cách duy nhất tôi có thể nghĩ đến là: trên sự kiện được đổi tên, tôi kiểm tra giao diện người dùng của mình để xem liệu tôi có một mục tương ứng với đường dẫn sự kiện hay không. Nếu vậy, tôi gắn cờ nó để đổi tên. Nếu không, tôi kiểm tra xem một mục đã được gắn cờ để đổi tên hay không và nếu có thì tôi đổi tên nó thành đường dẫn sự kiện mới. Nhưng tôi thực sự không thích ý tưởng này ...

Chỉnh sửa: Ok, tôi đã bổ sung điều gì đó dọc theo dòng "PS" của tôi: Tôi nhận thấy rằng khi đổi tên một cái gì đó, id của 2 sự kiện là các điều tra viên, để với id của sự kiện chứa tên mới, tôi có thể lấy sự kiện chứa tên cũ. Tôi chỉ cần sử dụng một từ điển nhỏ trong giao diện của tôi để lưu trữ id và các đường dẫn liên quan trong trường hợp sự kiện "được đổi tên".

Dù sao, bây giờ tôi có thể bắt đổi tên sự kiện, và thậm chí di chuyển các sự kiện: khi bạn di chuyển một tập tin, đó là một "đổi tên thành" sự kiện được đánh bắt bởi các FSEventStream ...

Nhưng, tôi vẫn có một cuối cùng vấn đề: xóa. Khi tôi xóa nội dung nào đó, nó được chuyển vào thùng rác: Tôi nhận được sự kiện "được đổi tên". Nhưng vấn đề là tôi không nhận được sự kiện đổi tên thứ hai. Chỉ sự kiện "đã sửa đổi" trên tệp .DS_Store. Tôi cho rằng tệp này được Trình tìm kiếm sử dụng để biết tệp nào nằm trong thùng, v.v. Vì vậy, tôi có thể kiểm tra sửa đổi tệp này và nhận sự kiện "đổi tên" cuối cùng để phát hiện tệp đã được gửi vào thùng. Nhưng tôi đang sử dụng TotalFinder trong đó sử dụng Asepsis, mà sửa đổi cách Finder lưu trữ. DS_Store tập tin: Tôi không còn nhận được "sửa đổi" về điều này. Để tổng hợp: Tôi không thể phát hiện khi tệp được gửi đến thùng ...

Bất kỳ ý tưởng nào về cách tôi có thể thực hiện điều đó? Có thể sử dụng một cái gì đó khác hơn FSEvents để bắt chỉ sự kiện này?

Trả lời

13

Vâng, tôi không tìm thấy câu trả lời hoàn hảo cho câu hỏi của tôi, nhưng tôi tìm thấy một giải pháp mà tôi cuối cùng đã thực sự hài lòng với, vì vậy tôi nghĩ tôi có thể chia sẻ ^^

Như tôi đã nói, khi di chuyển các thứ vào thùng rác, nếu bạn chỉ xem 1 thư mục, bạn sẽ không bắt sự kiện được tạo khi hình ảnh được đưa vào thùng rác. Vì vậy, tôi quyết định làm như sau: Tôi có một lớp học tạo ra một luồng trên thư mục gốc ("/") để nó sẽ bắt tất cả các sự kiện -> điều này giải quyết vấn đề của các tập tin được gửi vào thùng rác, và tất cả những thứ như vậy. Sau đó, lớp này cho phép đăng ký các đại biểu trên các đường dẫn nhất định. Vì vậy, thay vì tạo nhiều luồng, tôi tạo một luồng lớn, sau đó lọc các sự kiện nếu cần và tạo nhiều đại biểu.

Vì vậy, tất cả tôi phải làm gì bây giờ khi tôi muốn xem các sự kiện vào một thư mục đặc biệt như sau:

[[FSEventsListener instance] addListener:self forPath:somePath]; 

Tôi chỉ phải tạo một thể hiện của FSEventListener khi khởi động ứng dụng, và phát hành nó khi ứng dụng dừng lại. Và tôi chỉ cần thực hiện 3 phương pháp sau đây sẽ được tự động gọi:

-(void)fileWasAdded:(NSString *)file; 
-(void)fileWasRemoved:(NSString *)file; 
-(void)fileWasRenamed:(NSString *)oldFile to:(NSString *)newFile; 

Nếu bạn quan tâm đến mã nguồn của tiện ích này chút, bạn có thể kiểm tra ở đây: http://blog.pcitron.fr/tools/macosx-imageviewer/ (tiện ích đã được bổ sung tại phiên bản 0.8)

Tôi đã phát triển nó như một phần của trình xem ảnh nhỏ để đồng bộ hóa giao diện người dùng với nội dung đĩa (nó hiển thị số lượng hình ảnh chứa trong mỗi thư mục, v.v.) tiện ích trong Utils/FSEventsListener.h/.m.

Và nếu có cơ hội nào ai đó thực sự tải các ứng dụng và hãy nhìn vào các nguồn khác nhau, nếu bạn tìm thấy bất cứ điều gì hữu ích (cải thiện hiệu suất/Tính năng, bất cứ điều gì) cảm thấy tự do để thả một bình luận/mail ^^

+0

rất hữu ích, cảm ơn mã của bạn :) –

+0

trên trang web của bạn không có nút gửi trên trang liên hệ, hãy cho tôi email của bạn, tôi muốn hỏi một số câu hỏi cho bạn. Cảm ơn :) –

+0

Tôi đã sửa biểu mẫu liên hệ trên trang web của mình. Tôi không biết cách gửi tin nhắn riêng trên StackOverflow (hoặc thậm chí nếu có thể ^^) – Citron

4

Bạn đang thực sự tăng hai vấn đề liên quan đến FSEvents và đổi tên. 1. Một tệp được đổi tên và cả tên tệp cũ và mới nằm trong cây thư mục đang được giám sát. 2. Một tệp được đổi tên và một trong các tên không nằm trong cây thư mục đang được giám sát.

Bạn đã giải quyết (gần như) vấn đề đầu tiên. Nó cũng cần thiết để cung cấp cho ứng dụng của bạn một phương tiện để biết sự kiện nào đang được báo cáo trong cùng một nhóm sự kiện FSEvent. Phương pháp của bạn biết rằng hai đổi tên được báo cáo liên tiếp chỉ hoạt động nếu chúng nằm trong cùng một nhóm các sự kiện được báo cáo trong cùng một khoảng thời gian trễ. Nếu hai sự kiện đổi tên kiểu 2 xảy ra cái khác nhưng không nằm trong cùng một nhóm sự kiện được báo cáo trong cùng một nhóm độ trễ, chúng thực sự không liên quan gì đến nhau - và bạn sẽ nhầm tưởng rằng một tệp đã được đổi tên thành một tệp khác .

Có thể xử lý loại thay đổi thứ hai bằng cách chỉ theo dõi mọi thư mục trong hệ thống bằng cách sử dụng thư mục gốc, nhưng điều này sẽ làm ngập bạn với nhiều sự kiện không cần thiết. Bạn có thể xác định nếu đổi tên "một phần" là kết quả của một tệp đang được di chuyển ra khỏi cây thư mục đang được giám sát hoặc vào cây thư mục đang được giám sát bằng cách thực hiện một stat() trên tệp. Nếu stat() không thành công với sai số 2, thì tệp đã được di chuyển ra ngoài thư mục đang được theo dõi và có thể được xử lý như thể nó đã bị xóa. Nếu stat() thành công, sự kiện có thể được xử lý như thể tệp đã được tạo.

+0

Cách tiếp cận stat có một điều kiện chủng tộc: có migh đã được một chuỗi di chuyển, ví dụ, do đó, stat trên một con đường ở giữa trình tự sẽ thất bại. –

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