删除当前未被访问的文件


Delete file if currently not being accessed

我正在寻找一个需要删除日志文件的解决方案,但可能在进行删除调用时正在访问这些文件。所谓被访问,我的意思是一个进程要么读取文件,要么写入文件。在这种情况下,我需要跳过文件而不是删除它。此外,我的服务器是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编辑的情况下有用)

欢迎任何建议/见解。。。

通常情况下,如果没有管理权限,您将无法发现这一点(即,能够运行lsof等工具来查看是否列出了您的文件)。但是,如果您的脚本运行在linux/unix服务器上(大多数主机都是这样),那么您就不需要麻烦了,因为文件系统会处理这一问题。例如,你有1GB的文件,有人正在下载这个文件。如果下载程序刚刚启动,您可以安全地删除文件(使用unlink()或任何其他方式)事件,并且它不会干扰他的下载,因为文件系统知道文件已经打开(一些进程持有句柄),所以它只会标记它,比如说invisible(所以一旦你尝试列出文件夹内容,你将不再看到该文件,但如果你的文件足够大,你可以尝试检查可用的磁盘空间(即使用df,查看它是否仍被占用),但那些保留句柄的人仍然可以使用它。一旦所有进程关闭,它们的句柄文件将从介质中物理删除,并释放磁盘空间。因此,只需在需要时取消链接即可。如果您担心unlink可能引发的警告(在Windows上可能会出现这种情况),那么只需在调用前加上@标记(@unlink()),即可禁用此调用在运行时中可能引发的任何警告

您只需以这种方式更改代码(如果重复执行):

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

注意@以避免在文件不可删除的情况下出现错误,并且缺少结束标记(结束标记是常见错误的来源,应该避免)