2012-10-10 25 views
5

Tôi muốn tìm ra một cách để cảnh báo một tập lệnh python mà một tập tin được thực hiện sao chép. Đây là kịch bản:Làm thế nào để bạn kiểm tra khi một tập tin được thực hiện được sao chép bằng Python?

  1. Một thư mục, to_print đang được theo dõi bởi kịch bản bằng cách liên tục bỏ phiếu với os.listdir().

  2. Mỗi lần os.listdir() trả về danh sách các tệp tồn tại chưa từng thấy trước đó, tập lệnh thực hiện một số thao tác trên tệp đó, bao gồm mở tệp và thao tác nội dung của tệp.

Điều này là tốt khi tập tin là nhỏ, và sao chép các tập tin từ nguồn gốc của nó vào thư mục đang được theo dõi mất ít thời gian hơn so với lượng thời gian còn lại cho đến khi cuộc bầu cử tiếp theo bằng cách os.listdir(). Tuy nhiên, nếu một tệp được thăm dò và tìm thấy, nhưng nó vẫn đang trong quá trình được sao chép, thì nội dung tệp bị hỏng khi tập lệnh cố thực hiện hành động đó.

Thay vào đó, tôi muốn có thể (sử dụng os.stat hoặc cách khác) biết rằng tệp hiện đang được sao chép và đợi cho đến khi tôi thực hiện tác vụ đó nếu có.

Ý tưởng hiện tại của tôi là sử dụng os.stat() mỗi khi tôi tìm tệp mới, sau đó đợi đến lần thăm dò tiếp theo và so sánh ngày sửa đổi/tạo thời gian kể từ lần cuối cùng tôi thăm dò ý kiến. "ổn định", nếu không hãy tiếp tục bỏ phiếu cho đến khi nó được. Tôi không chắc chắn điều này sẽ làm việc mặc dù như tôi không quá quen thuộc với cách Linux/Unix cập nhật các giá trị này.

Trả lời

1

Vì các tệp có thể được sao chép trong khoảng thời gian thăm dò, chỉ xử lý các tệp mới được tìm thấy trong cuộc thăm dò cuối cùng trước khi kiểm tra tệp mới. Nói cách khác, thay vì điều này:

while True: 
    newfiles = check_for_new_files() 
    process(newfiles) 
    time.sleep(pollinterval) 

Làm điều này:

newfiles = [] 

while True: 
    process(newfiles) 
    newfiles = check_for_new_files() 
    time.sleep(pollinterval) 

Hoặc chỉ cần đặt chờ đợi ở giữa vòng lặp (giống hiệu lực thực sự):

while True: 
    newfiles = check_for_new_files() 
    time.sleep(pollinterval) 
    process(newfiles) 
+0

này sẽ không hoạt động nếu không có file để xử lý và các thư mục rỗng. – emish

+0

@emish, tại sao không? Sẽ không 'newfiles' chỉ là một danh sách trống, và chắc chắn 'process' có thể xử lý một danh sách rỗng một cách hợp lý. (Nếu nó không thể, sau đó nó cần được điều chỉnh để nó có thể.) – huon

+0

@ kindall Lời xin lỗi của tôi. Tôi đã không nhận ra sự khác biệt cho đến khi tôi thử nó. Cảm ơn, đây chính xác là hack ngắn mà tôi cần! – emish

2

Hãy thử inotify.

Đây là chuẩn Linux để xem tệp. Đối với trường hợp sử dụng của bạn, sự kiện IN_CLOSE_WRITE có vẻ đầy hứa hẹn. Có một số Python library for inotify. Một ví dụ rất đơn giản (lấy từ there). Bạn sẽ cần sửa đổi nó để chỉ bắt các sự kiện IN_CLOSE_WRITE.

# Example: loops monitoring events forever. 
# 
import pyinotify 

# Instanciate a new WatchManager (will be used to store watches). 

wm = pyinotify.WatchManager() 
# Associate this WatchManager with a Notifier (will be used to report and 
# process events). 

notifier = pyinotify.Notifier(wm) 
# Add a new watch on /tmp for ALL_EVENTS. 
wm.add_watch('/tmp', pyinotify.ALL_EVENTS) # <-- replace by IN_CLOSE_WRITE 

# Loop forever and handle events. 
notifier.loop() 

Dưới đây là một tài liệu API mở rộng: http://seb-m.github.com/pyinotify/

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