0

Let's say I have a folder containing 99tf.txt, 40.txt, 65.txt , in any order

If the current script var is 40.txt: I would like it to delete 65.txt (or the next file)

I was looking into something like that:

$file='40.txt';


if ($handle = opendir('./log/')) {

    $entry= readdir($handle);

  //move pointer to 40.txt
    while ($file != $entry && $entry !== false) {
      $entry = readdir($handle)

    }

   //go to the next file
   $entry = readdir($handle)

  if(is_file('./log/'.$entry)){

    unlink('./log/'.$entry);
    }

}

But I would like to avoid to go into a loop each time since there could be a lot of files in the folder. So is there a way to change the $handle pointer to the '$file' directly and delete the next file?

lopata
  • 1,325
  • 1
  • 10
  • 23
  • Do you know that filenames are always going to increment logically through the alphabet or is this just a bad example – RiggsFolly Oct 19 '15 at 09:50
  • no it's bad exemple, the names could be "654650.txt" and the next one"655699.txt" ...etc – lopata Oct 19 '15 at 09:54
  • 1
    Will this even work with `opendir`? http://stackoverflow.com/questions/541510/php-readdir-not-returning-files-in-alphabetical-order, I know for a fact it won't list the files in alpha-numerical order, but in file system order. – Flosculus Oct 19 '15 at 09:58
  • since it is random, you can implement some kind of a lookup table where you pick the file name on the very next line – Mi-Creativity Oct 19 '15 at 10:00
  • Can you explain how you know the filename of the file before the one you want to delete, but not the filename of the file you actually want to delete? – RiggsFolly Oct 19 '15 at 10:00
  • @Flosculus The order doesn't matter, – lopata Oct 19 '15 at 10:01
  • @RiggsFolly, The current filename is the ip of the visitor, I just want to delete the log next to him if it hasn't been modified since more than 20 minutes to make some space automatically when someone connects – lopata Oct 19 '15 at 10:04
  • That sounds _dangerously random_ – RiggsFolly Oct 19 '15 at 10:06
  • @lopata Can't you simply delete the oldest log (which is still older than 20 minutes), when the directory reaches a certain population? You don't need clever loops for that, just `array`, `filemtime`,and `sort`. – Flosculus Oct 19 '15 at 10:10
  • @Flosculus I wish I could do that, but I would like my pages to be executed with no delay, so I need to delete it without any loops or search function – lopata Oct 19 '15 at 10:14
  • Thats only a problem depending on how often you need to delete them. A single file IO per page request is nothing really, Apache does like 100 of those anyway. – Flosculus Oct 19 '15 at 10:17
  • Is this answer any use to you http://stackoverflow.com/questions/1785039/php-find-oldest-file-in-a-folder – RiggsFolly Oct 19 '15 at 10:32
  • 1
    I finally opted for an external script that deletes all old logs every 15 minutes http://stackoverflow.com/questions/2205738/how-to-delete-files-from-directory-based-on-creation-date-in-php – lopata Oct 19 '15 at 10:37

2 Answers2

0

If you don't mind using scandir, then this should work better for you.

$file = '40.txt';
$contents = scandir('./log/');

// Should already be sorted, but do again for safe measure
sort($contents);

// Make sure the file is in there.
if (false !== $index = array_search($file, $contents)) {

    // If the file is at the end, do nothing.
    if ($index !== count($contents)) {

        // Remove the next index
        unlink('./log/' . $contents[$index + 1]);
    }
}

In regard to the order not mattering, you don't need to sort it. Worth noting however, is that your method, takes longer, but uses less memory, while this method is the reverse, much faster, but potentially more memory consumption.

Flosculus
  • 6,880
  • 3
  • 18
  • 42
  • Isn't the scandir taking as much ressource than browsing all the files like I did? Moreover the count( takes lot of ressource – lopata Oct 19 '15 at 10:08
  • It is perform in a single IO operation, it uses more resources, but it performs it faster. Max memory used will be (on Linux), `(2 ^ 15) * avg(file_name_length)`. But I doubt you will want to let it reach 32,000 files. – Flosculus Oct 19 '15 at 10:13
  • So, is it possible to replace `count($contents)` with `if ($contents[$index+1 ]!== undefined)` – lopata Oct 19 '15 at 10:18
  • @lopata No, you're thinking of Javascript, it would be `if (isset($contents[$index+1]))` – Flosculus Oct 19 '15 at 10:19
0
<?php 
    $file = '40.txt';
    $scan_folder = scandir('./log/');
    $num_files = count($scan_folder);

    if ($num_files > 1) {
    $file_key = array_search($file, $scan_folder) +1;
    unlink('./log/'.$file_key);
    } else {
    // here you will preserve only 1 file all others can be removed every time this script is executed
    }
?>
Red Acid
  • 217
  • 1
  • 3
  • 14