2012-08-29 26 views
5

我正在尋找一種解決方案,我需要刪除日誌文件,但可能存在刪除調用時訪問它們的可能性。通過訪問,我的意思是一個過程是讀或寫文件。在這種情況下,我需要跳過該文件而不是刪除它。另外我的服務器是Linux和PHP在Apache上運行。如果當前未被訪問,則刪除文件

我所尋找的是類似(in pseudo-code)的東西:

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

現在我的問題是如何可以我定義being_accessed?我知道在PHP中可能沒有直接使用語言功能。我正在考慮使用部分的組合像last_access_time(也許?)和flock(但是這僅僅是在那些條件所在的文件是由flock訪問應用-ed有用)

任何建議/洞察力歡迎...

+0

你如何定義「正在訪問」文件? –

+0

可能有一個進程讀取它或寫入它.. –

+1

在Linux上並不重要,文件將不會實際刪除,直到所有文件指針都將被關閉。 – SirDarius

回答

6

一般來說,如果沒有管理權限(即能夠運行諸如lsof之類的工具來查看您的文件是否已列出,您將無法找到該文件,但是如果您的腳本在linux/unix服務器上運行這是大多數主機的情況),那麼你不需要打擾,因爲文件系統會照顧到這一點,例如,你有1GB的文件,並且有人正在下載這個文件,這對你來說是安全的。 unlink()或任何其他方式)事件,如果該下載器剛剛開始,並且它不會干擾他的下載,因爲文件系統知道該文件已經打開(某些進程持有句柄),因此它只會標記它,讓其他人(比如說invisible)您嘗試列出文件夾內容,您將不再看到該文件,但是如果文件足夠大,您可以嘗試檢查可用磁盤空間(即與df,看看它仍然會被佔用))但那些如何保持手柄仍然能夠使用它。一旦所有進程關閉其句柄文件,將從介質和磁盤空間中物理刪除。所以只需在需要時取消鏈接。如果你理會警告unlink可能會拋出(這可能是在Windows的情況下),那麼就在前面加上@馬克(@unlink())您的來電禁用此調用可能會在運行時拋出任何警告

+0

在這種情況下刪除是否爲阻塞呼叫?就像一個進程在一個循環中寫入它,並且存在對它的刪除調用一樣。將刪除塊直到寫入進程結束? –

+1

編號'unlink'將立即返回,就像沒有人使用該文件一樣。 –

+0

聽起來非常適合我在做什麼,謝謝! –

1

你會簡單地改變你的代碼這種方式(如果你重複做):

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

通知的@以避免收到的情況下,一個錯誤的文件是不可刪除,而且缺乏結束標記(結束標記是常見的錯誤來源,並應要避免)

相關問題