2012-08-29 43 views
5

Tôi đang tìm một giải pháp tôi cần xóa các tệp nhật ký, nhưng có thể có khả năng chúng đang được truy cập tại thời điểm thực hiện cuộc gọi xóa. Bằng cách được truy cập, tôi có nghĩa là một quá trình là đọc hoặc ghi vào tập tin. Trong những trường hợp như vậy, tôi cần phải bỏ qua tệp thay vì xóa nó. Ngoài ra máy chủ của tôi là Linux và PHP đang chạy trên Apache.Xóa tập tin nếu hiện tại không được truy cập

Những gì tôi đang tìm kiếm là một cái gì đó tương tự như (in pseudo-code):

<?php 
$path = "path_to_log_file"; 
$log_file = "app.log"; 
if(!being_accessed($log_file)) 
{ 
    unlink($path.$log_file); 
} 
?> 

Bây giờ câu hỏi của tôi là làm thế nào có thể tôi xác định being_accessed? Tôi biết có thể không có một chức năng ngôn ngữ làm điều này trực tiếp trong PHP. Tôi đang suy nghĩ về việc sử dụng kết hợp các phần như last_access_time (có thể?) Và flock (nhưng điều này chỉ hữu ích trong các điều kiện mà tệp được ứng dụng truy cập flock truy cập)

Mọi đề xuất/thông tin chi tiết chào mừng ...

+0

cách bạn xác định tệp "đang truy cập"? –

+0

Có thể có một quá trình hoặc đọc nó, hoặc viết nó .. –

+1

không quan trọng trên linux, các tệp sẽ không thực sự bị xóa cho đến khi tất cả các tệp con trỏ đến nó sẽ bị đóng. – SirDarius

Trả lời

6

Nói chung bạn sẽ không thể tìm ra điều đó mà không có quyền quản trị (và có thể chạy các công cụ như lsof để xem tệp của bạn có được liệt kê hay không. Nhưng nếu tập lệnh của bạn đang chạy trên máy chủ linux/unix (đó là trường hợp cho hầu hết các host) thì bạn không cần phải bận tâm, bởi vì hệ thống tập tin sẽ xử lý vấn đề này.Ví dụ, bạn có 1GB file và ai đó đang tải tập tin này. unlink() hoặc bất kỳ cách nào khác) nếu trình tải xuống vừa mới bắt đầu và nó sẽ không ảnh hưởng đến việc tải xuống của mình, bởi vì hệ thống tệp biết tệp đó đã được mở (một số quy trình lưu giữ) để chỉ đánh dấu nó, giả sử invisible cho người khác (vì vậy một lần bạn cố gắng liệt kê nội dung thư mục bạn sẽ không còn thấy tệp đó nữa, nhưng nếu tệp của bạn đủ lớn, bạn có thể thử kiểm tra không gian đĩa sẵn có (ví dụ: với df, để xem nó vẫn sẽ bị chiếm đóng)) nhưng những cách giữ tay cầm sẽ vẫn có thể sử dụng nó. Một khi tất cả các quy trình đóng tập tin xử lý của họ sẽ được gỡ bỏ vật lý từ phương tiện truyền thông và không gian đĩa giải phóng. Vì vậy, chỉ cần hủy liên kết khi cần. Nếu bạn bận tâm về cảnh báo unlink có thể bị ném (có thể là trường hợp trên Windows), thì chỉ cần thêm cuộc gọi của bạn với số @ (@unlink()) để vô hiệu hóa bất kỳ cảnh báo nào mà cuộc gọi này có thể xảy ra trong thời gian chạy

+0

Liệu lệnh xóa có phải là lệnh chặn trong các trường hợp như vậy không? Như trong nếu một quá trình được viết cho nó trong một vòng lặp, và có một cuộc gọi xóa chống lại nó .. sẽ xóa khối cho đến khi quá trình ghi kết thúc? –

+1

Không. 'Unlink' sẽ được trả về ngay lập tức, như thể không ai đang sử dụng tập tin đó. –

+0

Âm thanh hoàn hảo cho những gì tôi đang làm, cảm ơn! –

1

Bạn chỉ cần thay đổi mã của mình Bằng cách này (nếu bạn đang làm việc đó lặp đi lặp lại):

<?php 
$path = "path_to_log_file"; 
$log_file = "app.log"; 
@unlink($path.$log_file); 

thông báo các @ để tránh nhận được một lỗi trong trường hợp file không thể xóa, và sự thiếu kết thúc tag (kết thúc vào thẻ là nguồn gốc của lỗi phổ biến và nên tránh được)

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