Monday, January 23, 2012

Check if a file is opened in use or locked by another process

The PHP flock() function is good when the file locking method is used the same way by all programs that will lock the file.

However, you can't check if any process in the system is actually using the file or not. If you for example are monitoring an incoming ftp folder, you don't want to start processing a file until the file is completely tranferred (i.e. wait until the ftp daemon is no longer having the file open).

The following code illustrates how the command lsof (Linux) or fstat (FreeBSD) can be used for the purpose:

lsof on Linux:
<?php
$filename = "locktest.txt";
$directory = ".";
while (1) {
        $result = exec("lsof +D $directory | grep -c -i $filename");
        if ($result == "0") {
                echo "$directory/$filename is NOT open ($result)\n";
        } else {
                echo "$directory/$filename IS OPEN ($result)\n";
        }
        sleep(1);
};
?>

fstat on FreeBSD:
<?php
$out = exec('fstat test.pdf | wc -l');
$out = trim($out);

if ($out == 1) {
  echo 'not in use' . PHP_EOL;
}
else {
  echo 'in use' . PHP_EOL;
}
?>

test.sh:
#!/bin/sh

dir="/home/backup/"

find "${dir}" -type f | while read file
do
  isFileInUse=`fstat "${file}" | grep -c "${file}"`

  #echo "${isFileInUse}"

  if [ "${isFileInUse}"  = "0" ]; then
    #echo ${isFileInUse}
    echo "File is Not in use. ${file}"
  else
    echo "File is in use. ${file}"
  fi
done

Reference:
http://nerdia.net/2011/01/17/check-if-a-file-is-open-by-another-process-in-php-linuxunix/

No comments: