2012-08-29 24 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); 

通知的@以避免收到的情况下,一个错误的文件是不可删除,而且缺乏结束标记(结束标记是常见的错误来源,并应要避免)

相关问题