2012-02-07 21 views
7

Tôi có một thư mục mà tập tin được sao chép. Tôi muốn xem và xử lý tệp ngay khi chúng được sao chép vào thư mục. Tôi có thể phát hiện khi một tệp nằm trong thư mục, cho dù thông qua bỏ phiếu (triển khai hiện tại của tôi) hay trong một số thử nghiệm bằng cách sử dụng API Windows từ một vài mẫu tôi đã tìm thấy trực tuyến.Xem thư mục C++ - Cách phát hiện sao chép đã kết thúc

Vấn đề là tôi phát hiện khi tệp được tạo lần đầu và tệp vẫn được sao chép. Điều này làm cho chương trình của tôi, cần truy cập vào tệp, thông qua lỗi (vì tệp chưa hoàn tất). Làm thế nào tôi có thể phát hiện không khi bắt đầu sao chép nhưng khi sao chép kết thúc? Tôi đang sử dụng C + + trên Windows, do đó, câu trả lời có thể là nền tảng phụ thuộc nhưng, nếu có thể, tôi muốn nó được nền tảng bất khả tri.

+0

Tôi đã tìm thấy câu hỏi này chỉ vài phút trước: http://stackoverflow.com/questions/559659/how-to-know-a-file-is-finished-copying Nó rất giống với vấn đề của tôi nhưng "được phê duyệt "giải pháp là xa được thanh lịch và chức năng. – petersaints

+0

Nếu mã của bạn sẽ chạy trong ngữ cảnh quản trị, tức là, dưới dạng dịch vụ hệ thống, bạn có thể sử dụng nhật ký thay đổi. Xem http://msdn.microsoft.com/en-us/library/windows/desktop/aa363798%28v=vs.85%29.aspx –

+0

Xem xét khả năng những thứ như sao chép ngây thơ bằng cách sử dụng 'fread()'/'fwrite() 'Tôi không nghĩ rằng có một giải pháp chung. Không khá mạnh mẽ, nhưng có thể bằng cách theo dõi mở xử lý các tập tin? –

Trả lời

4

Bạn có thể sử dụng tệp khóa hoặc quy ước đặt tên đặc biệt. Cách dễ nhất là thứ hai và sẽ hoạt động như sau:

Giả sử bạn muốn di chuyển tệp có tên "fileA.txt" Khi sao chép tệp vào thư mục đích, thay vào đó, hãy sao chép tệp đó vào "fileA.txt.partial" hoặc một cái gì đó như thế. Khi bản sao hoàn tất, đổi tên tệp từ "fileA.txt.partial" thành "fileA.txt". Vì vậy, sự xuất hiện của "fileA.txt" là nguyên tử như xa như chương trình xem có thể nhìn thấy.

Tùy chọn khác như đã đề cập trước đó là tệp khóa. Vì vậy, khi bạn sao chép tệp có tên "fileA.txt", trước tiên bạn tạo tệp có tên "fileA.txt.lock". Khi sao chép xong, bạn chỉ cần xóa tập tin khóa. Khi chương trình xem thấy "fileA.txt", nó sẽ kiểm tra xem "fileA.txt.lock" tồn tại, nếu có, nó có thể đợi hoặc xem lại tập tin đó trong tương lai khi cần thiết.

+2

Đó là giải pháp thay thế và có thể hoạt động trên các môi trường khác. Nhưng trong trường hợp này, tôi đang nói về các tập tin được sao chép bởi các chương trình khác/thông qua tập tin thám hiểm vào một thư mục đang được theo dõi bởi chương trình của tôi. Trong trường hợp đó, cách tiếp cận này rất khó thực hiện. – petersaints

+0

Không chắc chắn điều đó có thể xảy ra nếu bạn không có quyền kiểm soát cách sao chép các tập tin. –

2

Bạn không nên bỏ phiếu. Sử dụng FindFirstChangeNotification (http://msdn.microsoft.com/en-us/library/windows/desktop/aa364417%28v=vs.85%29.aspx) để xem thư mục để thay đổi.

Sau đó, sử dụng các chức năng Đợi (http://msdn.microsoft.com/en-us/library/windows/desktop/ms687069%28v=vs.85%29.aspx) để chờ thông báo thay đổi xảy ra.

Tổng quan và ví dụ ở đây: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365261%28v=vs.85%29.aspx

Tôi không chắc chắn cách chính xác tập tin ghi hoàn thành có thể được xác định. Câu trả lời của Evan Teran là một ý kiến ​​hay.

+0

Đó là chính xác bởi vì bỏ phiếu không phải là một ý tưởng tốt mà tôi đang cố gắng để thay thế nó bằng một cái gì đó tốt hơn;) Và yeah! Tôi đã tìm thấy các phương pháp đó và tôi đã có một giải pháp dựa trên điều này: http://code.google.com/p/simplefilewatcher/. Vấn đề là để xác định hoàn thành ghi tập tin. Thư viện đó (mà tôi đã sửa đổi một chút) sử dụng ReadDirectoryChangesW mà tôi tin rằng nó thậm chí còn mạnh hơn FindFirstChangeNotification. – petersaints

+0

Trên một lưu ý phụ, tôi tự hỏi làm thế nào Dropbox (ví dụ) đề với loại vấn đề này. – petersaints

+0

Bạn có thể thử mở tệp để ghi độc quyền, sẽ không thành công cho đến khi bản sao hoàn tất. Có lẽ có một cách để ngăn chặn tình trạng đó, thay vì bỏ phiếu, nhưng tôi không biết điều đó. –

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