FindTopSize.php
php
<?php
class FindTopSize
{
public static $out_process = false;
public static function findTop($directory, $handle = 'file', $limit = 10)
{
switch ($handle) {
case 'file':
$files = [];
self::listFilesWithSize($files, $directory);
$s = self::findTopFileSort($files, $limit);
break;
case 'dir':
$dirs = [];
self::listDirWithSize($dirs, $directory);
$s = self::findTopDirSort($dirs, $limit);
break;
default:
$s = [];
break;
}
self::out($s);
}
private static function findTopDirSort($arr, $limit)
{
array_multisort(array_column($arr, 'len'), SORT_DESC, $arr);
$pk = end($arr)['key'];
foreach ($arr as $key => $item) {
if(self::$out_process===true){
echo $key."\n";
}
if($key===$pk)
continue;
$arr[sha1(substr($item['handle'],0,strrpos($item['handle'],'/')))]['size'] += $arr[$key]['size'];
}
array_multisort(array_column($arr, 'size'), SORT_DESC, $arr);
$p = 1;
foreach ($arr as $item) {
if ($p > $limit) {
break;
}
$p++;
$res[] = $item;
}
return $res;
}
private static function findTopFileSort($arr, $limit)
{
array_multisort(array_column($arr, 'size'), SORT_DESC, $arr);
$res = [];
$p = 1;
foreach ($arr as $item) {
if ($p > $limit) {
break;
}
$p++;
$res[] = $item;
}
return $res;
}
private static function listFilesWithSize(&$files, $dir)
{
$handles = array_merge(glob($dir . '/.*'), glob($dir . '/*'));
unset($handles[0]);
unset($handles[1]);
foreach ($handles as $handle) {
if(self::$out_process===true){
echo $handle . "\n";
}
if (is_dir($handle)) {
self::listFilesWithSize($files, $handle);
}
if (is_file($handle)) {
$files[] = [
'handle' => $handle,
'size' => filesize($handle),
];
}
}
}
private static function listDirWithSize(&$dirs, $dir)
{
if (count($dirs) === 0) {
$dirs[sha1($dir)] = [
'key' => sha1($dir),
'pkey' => '',
'handle' => $dir,
'size' => 0,
'len' => strlen($dir),
];
}
$handles = array_merge(glob($dir . '/.*'), glob($dir . '/*'));
unset($handles[0]);
unset($handles[1]);
foreach ($handles as $handle) {
if(self::$out_process===true){
echo $handle . "\n";
}
if (is_dir($handle)) {
$dirs[sha1($handle)] = [
'key' => sha1($handle),
'pkey' => sha1($dir),
'handle' => $handle,
'size' => 0,
'len' => strlen($handle),
];
self::listDirWithSize($dirs, $handle);
}
if (is_file($handle)) {
if (!empty($dirs[sha1($dir)]))
$dirs[sha1($dir)]['size'] += filesize($handle);
}
}
}
private static function out($arr)
{
echo "\n\n";
foreach ($arr as $item) {
echo self::convertSize($item['size']) . ' -> ' . $item['handle'] . "\n";
}
}
private static function convertSize($size)
{
$units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB',];
for ($i = 0; $size >= 1024 && $i < count($units) - 1; $i++) {
$size /= 1024;
}
return sprintf("%10s", sprintf("%.3f", round($size, 3)) . ' ' . $units[$i]);
}
}
运行
run.php
php
<?php
ini_set('memory_limit', '-1');
include_once 'D:/code/FindTopSize.php';
$time_start = time();
$directory = 'C:';
FindTopSize::$out_process = true;
FindTopSize::findTop($directory,'file',10);
//FindTopSize::findTop($directory, 'dir', 20);
$time_end = time();
// 计算执行时间
$time = $time_end - $time_start;
$time_s = secondsToTime($time);
echo "\n程序执行时间:".$time_s." \n";
function secondsToTime($seconds) {
$hours = floor($seconds / 3600);
$minutes = floor(($seconds % 3600) / 60);
$seconds = $seconds % 60;
$s = $hours.'时'.$minutes.'分'.$seconds.'秒';
return $s;
}
执行
php -f run.php
开启cli模式开启jit效果更佳,扫描C盘【30万文件】目录大小耗时5分钟