ディレクトリ内の容量制限

[上に] [前に] [次に]
さとる 2000/01/17(月) 23:55:29
ブラウザから画像をアップロードするフォームメール(perl UNIX)を
使っているのですが、
ディスク容量の関係もあり、ある程度の容量になったら、古い画像を削除したいと思っています。

if (!opendir(DIR, "$dir")) { &error; }
@ls = readdir(DIR);
closedir(DIR);

$totalsize = 0;
foreach $line (@ls) {
  $filesize = (-s $dir\/$line);
  $totalsize = $totalsize + $filesize;
  $utime  = utime "$dir\/$line";

  if ($new_utime == 0) {
   $value = $line; $new_utime = $utime;
  } elsif ($utime < $new_utime) {
   $value = $line;
  }
  $new_utime = $utime;
}

if ($totalsize > $max) {
  if (!unlink "$dir\/$value") { &error; }
}

として、削除しようと思っているのですが、どうもうまくいきません。
根本的な考え方がまちがっているのかもしれませんが、
いい方法がありましたら教えて下さい

きたむら 2000/01/18(火) 02:47:53
utimeはタイムスタンプを書き換える関数で、更新時刻の取得には使えません。
次のようにstatを使って書き直せば、あとは大きな問題はないと思います。

× $utime = utime "$dir/$line";

○ $utime = (stat "$dir/$line")[9];

さとる 2000/01/18(火) 16:55:00
ありがとうございます。
statに変えたら、削除できるようになりました。

ただ、一番古いものは残って、2番目に古いものから削除されていきます。なぜだろう……。
もう少しテストしてみます。ありがとうございました。

Syn [E-Mail] 2000/01/18(火) 17:09:17
>   if ($new_utime == 0) {
>    $value = $line; $new_utime = $utime;
>   } elsif ($utime < $new_utime) {
>    $value = $line;
>   }
>   $new_utime = $utime;



  if ($new_utime == 0) {
   $value = $line; $new_utime = $utime;
  } elsif ($utime < $new_utime) {
   $value = $line;
    $new_utime = $utime;  # <- 中に
  }

でないと、毎回 $new_utime が書き換えられてますよ。

Nobu3 2000/01/18(火) 18:15:58
ディレクトリを排除してないからとか?
next if $line =~ /^\./;
を foreach のすぐ下に書いてみてはどうでしょう?

あと、
$new_utime = time();
を foreach の前に書いておくと、if文が少しすっきりするかも。

さとる 2000/01/18(火) 19:59:27
皆さんありがとうございます。

> $new_utimeの位置
については、まさにその通りでした(^^;
ただ、それでもうまくいかないので
> next if $line =~ /^\./;
を入れたところ、とたんにうまくいくようになりました。
これって、「ディレクトリの中にディレクトリが入っている場合」
だと思っていたので、半信半疑だったのですが、
なぜうまくいったんでしょう。画像ファイルしか入っていないのに...


>$new_utime = time();
>を foreach の前に書いておくと、if文が少しすっきりするかも。

たしかに不格好だなとは思っていたのですが、
  if ($utime < $new_utime) {
   $value = $line;
   $new_utime = $utime;
  }
だけにしたらすっきりしました。
ありがとうございました。

Nobu3 2000/01/19(水) 03:14:13
えと、ディレクトリについて補足です。

ディレクトリを読込んだときは、必ず「.(このディレクトリを示す)」と「..(親ディレクトリを示す)」の2つが入ります。
なので、「.」で始まるファイル(ディレクトリ)を無視すればどうだろう?と思ったのです。
動作が怪しいときは、取得した値を表示すると理解できることもあります。
print "Content-type: text/plain\n\n";
print "$_\n" foreach(@ls);

ちなみに、この方法では、普通のディレクトリなら無視しないので、
ディレクトリかどうかを調べる必要も出てくるでしょう。
next if(-d "$dir/$line");
とか、
next unless(-f "$dir/$line");
とか。

さとる 2000/01/19(水) 19:31:24
[[解決]]
>ディレクトリを読込んだときは、必ず「.(このディレクトリを
>示す)」と「..(親ディレクトリを示す)」の2つが入ります。
なるほど、そうなんですね。
疑問が解けました。

>ディレクトリかどうかを調べる必要も出てくるでしょう。
ディレクトリのチェックについても書き加えたいと思います。
いろいろありがとうございました。

[上に] [前に] [次に]