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由访问应用程序编辑的情况下才有用)

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

4

2 回答 2

6

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

于 2012-08-29T19:16:36.093 回答
1

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

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

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

于 2012-08-29T19:18:26.303 回答