user4951
user4951

Reputation: 33138

How to limit the number of files returned by glob to save memory?

I made program to ocassionally scan directory and then delete old cache files.

Often the number of cache files are quite huge and I got out of memory error.

glob(cacheme_directory()."*");

How do I make glob to return limited number of files? Say first 50000. Then we will delete them and then at the next session we can delete again, etc.

This is not the same with Limit number of results for glob directory/folder listing

I need to reduce amount of memory used. Hence loading the whole thing and then removing things won't work.

This is the full program

if (mt_rand(0,1000)==0)
{

    $files = glob(cacheme_directory()."*");
    foreach($files as $file)
    {
        $filemtime=filemtime ($file);
        if (is_file($file) && time()-$filemtime>= $cacheAge)
        {
            unlink($file);
        }
    }
}

Upvotes: 2

Views: 4134

Answers (4)

Glavić
Glavić

Reputation: 43582

Try it with DirectoryIterator (PHP >= 5) :

$i = new DirectoryIterator( cacheme_directory() );
foreach ($i as $val) {
    if ($val->isFile()) {
        echo "{$val->getFilename()} ({$val->getMTime()})\n";
    }
}

Upvotes: 4

Sammitch
Sammitch

Reputation: 32272

Like @Dutow said: glob will return you an array of the entire directory, you can't change that.

An alternative to looping through the directory with PHP is to simply issue a shell command like:

find /path/to/cache/dir/ -type f -delete

Which will delete all files in the given directory. Or you can match certain names like:

find /path/to/cache/dir/ -type f -name 'cache*' -delete

This assumes you have access to either the shell() or shell_exec() commands, but will not require gobs of memory, and can be backgrounded by tacking on the & operator at the end of the command.

Upvotes: 1

Dutow
Dutow

Reputation: 5668

Glob will return you an array of the entire directory, you can't change that.

To read only a limited number of files into memory, check the opendir function in PHP, which let's you write your own loop on a resource.

Upvotes: 3

Shiplu Mokaddim
Shiplu Mokaddim

Reputation: 57690

You can not do it with glob. However you can use some wild card tricks. Like

glob(cacheme_directory()."1*");

This is return about one-tenth of files if their name starts only with numbers. If they hold only alphabetic characters you can use a* to get one-twenty-sixth of file names.

You can loop it.

for($i=0;$i<10;$i++){
    glob(cacheme_directory()."$i*");
}

or

for($i=ord('a');$i<=ord('z');$i++){
    glob(cacheme_directory().chr($i)."*");
}

Upvotes: 2

Related Questions