Форум программистов, компьютерный форум, киберфорум
PHP для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/15: Рейтинг темы: голосов - 15, средняя оценка - 4.60
18 / 13 / 6
Регистрация: 04.04.2019
Сообщений: 827

Поиск пустых папок. Идеи и реализации

16.05.2019, 12:39. Показов 3390. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Ещё одна проблемка. Пробую написать код для поиска (без удаления) пустых папок. Удалять гораздо проще хотя бы потому, что rmdir не удаляет не пустую папку.
Были разные идеи. Пробовал использовать filesize, но любая папка видится с размером 0. Были другие мысли. Более менее получилась одна, основанная на сравнении имен путей папки и файла. Если в имени пути файла есть имя пути папки, то папка не пустая, если нет такого совпадения, то папка пустая. Пока разбираюсь с парой небольших багов этого способа. Есть ещё мысль задействовать count по принципу:
PHP
1
2
3
4
    if (0 < count(scandir(...)))
    {
       // папка не пустая
    }
но как-то с реализацией не срастается.
Может кто подскажет способ поиска пустых папок?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
16.05.2019, 12:39
Ответы с готовыми решениями:

Поиск пустых папок
Ребята помогите кто может. Нужна функция поиска пустых папок для файлового менеджера. Это все должно происходить без встроенных функций,...

Поиск пустых папок и файлов
Привет всем! Подскажите, пожалуйста, кто сталкивался, как средствами VB6, не прибегая к сторонним OCX, реализовать поиск пустых папок...

Поиск и удаление пустых папок, а также все вложенные пустые папки
Прошу люди гении, подскажите мне код на С++ для этой задачки. Я буду очень рад и благодарен вам.

14
 Аватар для Asiman
156 / 119 / 59
Регистрация: 27.04.2013
Сообщений: 351
16.05.2019, 12:47
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function RemoveEmptySubFolders($path)
{
  $empty=true;
  foreach (glob($path.DIRECTORY_SEPARATOR."*") as $file)
  {
     if (is_dir($file))
     {
        if (!RemoveEmptySubFolders($file)) $empty=false;
     }
     else
     {
        $empty=false;
     }
  }
  if ($empty) rmdir($path);
  return $empty;
}
0
18 / 13 / 6
Регистрация: 04.04.2019
Сообщений: 827
16.05.2019, 13:21  [ТС]
Цитата Сообщение от Asiman Посмотреть сообщение
function RemoveEmptySubFolders($path) { $empty=true; foreach (glob($path.DIRECTORY_SEPARATOR."*") as $file) { if (is_dir($file)) { if (!RemoveEmptySubFolders($file)) $empty=false; } else { $empty=false; } } if ($empty) rmdir($path); return $empty; }
Это же удаление пустых папок. Оно не нужно, способов удаления много, и ваш один из них. Да, он простой и действенный. Но удалять не нужно. Нужно составить список пустых папок. А из этой функции я не вижу как выудить поиск пустых папок, поскольку он основан на удалении любой. А rmdir может удалять только пустые, полные не удалит. Ну удалять же их, записывать удаление и потом восстанавливать.
0
3 / 3 / 1
Регистрация: 04.02.2016
Сообщений: 45
16.05.2019, 13:45
DyadyaGe, scandir не подходит?
0
Эксперт PHP
4925 / 3920 / 1620
Регистрация: 24.04.2014
Сообщений: 11,441
16.05.2019, 14:03
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$iter = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator(
        '/full/path/to/dir',
        FilesystemIterator::SKIP_DOTS
    ),
    RecursiveIteratorIterator::SELF_FIRST
);
 
$filter = new CallbackFilterIterator(
    $iter,
    function (SplFileInfo $file): bool {
        return $file->isDir() && count(scandir($file->getPathname())) === 2;
    }
);
 
foreach ($filter as $f) {
    var_dump($f->getPathname();
}
0
18 / 13 / 6
Регистрация: 04.04.2019
Сообщений: 827
16.05.2019, 14:33  [ТС]
Цитата Сообщение от deca Посмотреть сообщение
scandir не подходит?
Сам по себе он пустые папки не показывает... А так я его использовал в одном из вариантов при получении имени пути папки и пути файла. Да и в примере с count он тоже задействован.

Добавлено через 25 минут
Цитата Сообщение от Jewbacabra Посмотреть сообщение
PHP
$iter = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator(
'/full/path/to/dir',
FilesystemIterator::SKIP_DOTS
),
RecursiveIteratorIterator::SELF_FIRST
);
$filter = new CallbackFilterIterator(
$iter,
function (SplFileInfo $file): bool {
return $file->isDir() && count(scandir($file->getPathname())) === 2;
}
);
foreach ($filter as $f) {
var_dump($f->getPathname();
}
Вроде работает. Но есть пару вопросов (замечаний). Да, и я заменил var_dump на print_r, мне так наглядней.
1. Я пока не разобрался с простеньким пхп, а тут уже итерации, так что я просто не понимаю до конца как и что тут работает.
2. На моей проверочной папке с небольшим количеством папок и файлов сработало хорошо, можно сказать отлично, все проблемные места, которые до сих пор у меня были (квадратные скобки в имени, точка в начале имени) отсортировало как надо. Но когда указал букву диска выскочило несколько Нотисов, варнингов и потом фатал эрор. Возможно это связано с правами доступа.
Вот некоторые из них:
PHP
1
2
3
4
Warning: scandir(E:\$RECYCLE.BIN\S-1-5-18,E:\$RECYCLE.BIN\S-1-5-18): �������� � �������. (code: 5) in 
Warning: scandir(E:\$RECYCLE.BIN\S-1-5-18): failed to open dir: No such file or directory in
Warning: scandir(): (errno 2): No such file or directory in
Warning: count(): Parameter must be an array or an object that implements Countable in
Ну и фатал эрор
PHP
1
Fatal error: Uncaught UnexpectedValueException: RecursiveDirectoryIterator::__construct(E:\$RECYCLE.BIN\S-1-5-18,E:\$RECYCLE.BIN\S-1-5-18): �������� � �������. (code: 5) in ... iter.php:22 Stack trace: #0 [internal function]: RecursiveDirectoryIterator->__construct('E:\\$RECYCLE.BIN...', 4096) #1 [internal function]: RecursiveDirectoryIterator->getChildren() #2 ... iter.php(22): FilterIterator->rewind() #3 {main} thrown in ... iter.php on line 22
Ну а поскольку я в итерациях ноль, то крайне смутно догадываюсь, где ошибка. Можете дальше пояснить и подправить?
0
Эксперт PHP
4925 / 3920 / 1620
Регистрация: 24.04.2014
Сообщений: 11,441
16.05.2019, 14:57
Цитата Сообщение от DyadyaGe Посмотреть сообщение
Да, и я заменил var_dump на print_r, мне так наглядней.
Очень спорно. print_r не показывает типы и не показывает null.
Цитата Сообщение от DyadyaGe Посмотреть сообщение
Ну а поскольку я в итерациях ноль, то крайне смутно догадываюсь, где ошибка. Можете дальше пояснить и подправить?
Прав нету. И в целом лезть пыхой в системные директории ОС так себе идея. Но можно сделать так
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$iter = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator(
        '/full/path/to/dir',
        FilesystemIterator::SKIP_DOTS
    ),
    RecursiveIteratorIterator::SELF_FIRST | RecursiveIteratorIterator::CATCH_GET_CHILD
);
 
$filter = new CallbackFilterIterator(
    $iter,
    function (SplFileInfo $file): bool {
        return $file->isDir() && count((@scandir($file->getPathname())) ?: []) === 2;
    }
);
0
18 / 13 / 6
Регистрация: 04.04.2019
Сообщений: 827
16.05.2019, 15:27  [ТС]
Цитата Сообщение от Jewbacabra Посмотреть сообщение
Очень спорно. print_r не показывает типы и не показывает null.
А так это в моей частной ситуации. Так я их чередую ))) просто сразу выводит столбиком (добавляю перенос) построчно все элементы. А в этой ситуации мне так выгодней.

Цитата Сообщение от Jewbacabra Посмотреть сообщение
Прав нету. И в целом лезть пыхой в системные директории ОС так себе идея. Но можно сделать так
Тоесть я оказался прав с доступом? Хоть это хорошо, хоть что-то понимаю. Ну и на самом деле лезть в системные папки мыслей не было. Просто вывалился этот фатал эрор и выполнение прекратилось. Хотя чисто для понимания работы кода такое хотелось бы разобрать.
Ну и про ваш последний вариант. В этот раз показало только первую по алфавиту пустую папку и все. На диске Е видимо пропустило какую-то часть папок с ограниченным доступом, напечатало одну темповскую директорию, следующую по алфавиту, и все. Вы уж простите, что мучаю этим вопросом. Для меня реально пока что итерации темный лес. Надеюсь когда-то разберусь, а пока, раз уж такое дело, то хотелось бы полностью рабочее решение. Чтоб выводило именно все папки, не вываливалось при появлении папок с ограниченным доступом, ну и раз уж так заговорили, то чтоб и в них можно было заглянуть.
0
Эксперт PHP
4925 / 3920 / 1620
Регистрация: 24.04.2014
Сообщений: 11,441
16.05.2019, 15:36
Цитата Сообщение от DyadyaGe Посмотреть сообщение
В этот раз показало только первую по алфавиту пустую папку и все.
Ну да, так будет правильно
PHP
1
2
3
4
5
6
7
8
$iter = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator(
        '/full/path/to/dir',
        FilesystemIterator::SKIP_DOTS
    ),
    RecursiveIteratorIterator::SELF_FIRST,
    RecursiveIteratorIterator::CATCH_GET_CHILD
);
У себя использовал на диске D:, где занято около 200G, отработало нормально
0
18 / 13 / 6
Регистрация: 04.04.2019
Сообщений: 827
16.05.2019, 16:42  [ТС]
Цитата Сообщение от Jewbacabra Посмотреть сообщение
У себя использовал на диске D:, где занято около 200G, отработало нормально
Спасибо. У меня тоже все нормально, вроде ничего не пропустило. Только в папки с ограниченным доступом не полезло (((
Можно вариантик и с такой настройкой? Чисто для будущих экспериментов.
И ещё, можно вам показать свой вариант, где я сравнивал имена путей? у меня там небольшая проблемка, неправильно отсортировывает квадратные скобки в имени. Может и там подскажите? Правда я под этот вопрос другую тему начал.

Добавлено через 33 минуты
Да, и ещё такое уточнение. Если в папке лежит две-три-несколько пустых папок, считается ли это пустой папкой?
И самое главное и смешное. Теперь я не могу одним махом удалить пустые папки ))) Раньше было достаточно сделать типа варианта, который выше предложил Asiman, напр,
PHP
1
if ($empty) rmdir($path);  return $empty;
, ну или как вариант
PHP
1
if ($empty) @rmdir($folder);
а теперь не получается. Не использовать же старые варианты поиска пустых папок для их удаления. Можете подсказать как с помощью вашей функции настроить удаление?
0
Эксперт PHP
4925 / 3920 / 1620
Регистрация: 24.04.2014
Сообщений: 11,441
16.05.2019, 19:21
Цитата Сообщение от DyadyaGe Посмотреть сообщение
Только в папки с ограниченным доступом не полезло (((
Можно вариантик и с такой настройкой?
Если только от админа скрипт запустить.
Цитата Сообщение от DyadyaGe Посмотреть сообщение
И самое главное и смешное. Теперь я не могу одним махом удалить пустые папки
А ошибка при этом какая?
0
18 / 13 / 6
Регистрация: 04.04.2019
Сообщений: 827
16.05.2019, 19:56  [ТС]
Цитата Сообщение от Jewbacabra Посмотреть сообщение
Если только от админа скрипт запустить.
Честно говоря пока не умею. В Винде все понятно ))) там жмешь на файлик правой клавишей и выбираешь запуск от имени админа ))) Ну да почитаю, главное идею понял )
Цитата Сообщение от Jewbacabra Посмотреть сообщение
А ошибка при этом какая?
Никакой ошибки нет, просто удаляет по одной папке. Я её и в перебор foreach запихнул, а все равно не удаляет все скопом. Собственно говоря отсюда и вырос первый вопрос про пустые папки в которых ещё пустые папки. Получается rmdir сам по себе папку с пустой папкой не удалит, тем более, если таких пустых будет несколько. Нужно будет удалять сперва самые крайние пустые папки, потом окажется, что папка, в которой они лежали тоже пустая и нужно делать для неё проверку. Хотя можно и сразу натравить на неё rmdir. Просто, когда я сравнивал имена путей, то сперва были крайние, потом папка, в которой они лежали, ну и так, пока есть такие пустые вложения. А потом подсовывал rmdir этот список, и он одним махом все удаляет. Конечно у меня другая цель создания списка пустых папок, но хотелось результаты вашей функции использовать по полной.

Добавлено через 14 минут
Можно конечно разбить на две функции. Из одной в другую передавать список на удаление, но как-то по-моему не очень.
И ещё понаглею. Чтоб пока не читать про итерации, но легко пользоваться вашей функцией, не подскажите как подсовывать ей значение? Пробовал вставлять ей вместо пути переменную и перед функцией задавал переменной значение, но ругается на двойное значение
PHP
1
Fatal error: Uncaught UnexpectedValueException: RecursiveDirectoryIterator::__construct($dir,$dir): �� ������ ����� �������� ����. (code: 2) in ... iter.php:10 Stack trace: #0 ... iter.php(10): RecursiveDirectoryIterator->__construct('$dir', 4096) #1 {main} thrown in ... iter.php on line 10
0
18 / 13 / 6
Регистрация: 04.04.2019
Сообщений: 827
17.05.2019, 16:55  [ТС]
Попробовал загнать $f в массив вот так:
PHP
1
2
3
foreach ($filter as $f) {
$u[]=$f;
}
и вот так
PHP
1
2
3
4
foreach ($filter as $f) {
$s=($f->getPathname());
$u[]=$s;
}
Вообще перестало удалять, даже построчно.
0
18 / 13 / 6
Регистрация: 04.04.2019
Сообщений: 827
18.05.2019, 12:00  [ТС]
И ещё просьба. Подскажите, пжл, кто-нибудь как это решение "превратить" в функцию? Я до классов ещё не дорос, в обычных функциях путаюсь. Но тут очень красивое решение. Хотелось бы им уже пользоваться, а потом со временем разобраться как оно работает. А для этого нужно вызывать функцию с нужными параметрами (местом поиска). Пробовал делать вот так:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function iterac()
{
 $iter = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator(
        '',
        FilesystemIterator::SKIP_DOTS
    ),
    RecursiveIteratorIterator::SELF_FIRST,
    RecursiveIteratorIterator::CATCH_GET_CHILD
);
$filter = new CallbackFilterIterator(
    $iter,
    function (SplFileInfo $file): bool {
        return $file->isDir() && count((@scandir($file->getPathname())) ?: []) === 2;
    }
);
 
foreach ($filter as $f) {
//var_dump($f->getPathname());
print_r($f->getPathname()); echo '<br>';
} 
}
$iter=new RecursiveDirectoryIterator('.');
iterac($iter);
Но ругается. Пробовал подсовывать в строку
PHP
1
2
    new RecursiveDirectoryIterator(
        '',
переменную - ругается на двойное значение переменной.
0
18 / 13 / 6
Регистрация: 04.04.2019
Сообщений: 827
23.05.2019, 13:36  [ТС]
Пока жду ответа на вопрос, как запустить функцию с итерациями и классами, решил, раз уж тема называется "Поиск пустых папок. Идеи и реализация" выложить свой наиболее удачный вариант. Ищет как пустые папки, так и потенциально пустые, в которых нет файлов, но есть такие же пустые папки. Причем, если убрать отрицание во время сортировки, то получим список всех полных папок. Так же мою функцию можно легко дополнить строкой для удаления пустых папок. Есть небольшой баг. Если в имени папки есть квадратные скобки, то она попадает в список пустых даже если в ней есть файл, а если убрать отрицание, то наоборот. На готовое решение не тянет. Хочется доработать, убрать баг.
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
function find_empty($dir)
{
  global $files;global $folders;  global $annown;
  function find_file_folder($dir) // эта часть функции в функции ищет  папки и файлы
  {
      global $files;global $folders;
      foreach (glob($dir.DIRECTORY_SEPARATOR."*") as $annown)
      {
        if (is_dir($annown))
       {
          if (find_file_folder($annown)) continue;
           $folders[]=$annown;
          // echo $annown; echo '<br>';  // ищет  папки
         }
          else
          {
           $files[] =$annown;
           // echo $annown; echo '<br>';  //  ищет   файла
           }
         }
  }
  //$dir='.';
  find_file_folder($dir);  // тут вызывается поиск папок и файлов и передается ниже для сравнения строк
    foreach($files as $file)
   {
        foreach($folders as $folder)
      {
             $pos = strpos($file,$folder);
 if ($pos !== FALSE)
            {
                $folders_notempty[$folder] = $folder;
            }
        }
    }
     foreach($folders as $folder)
    {
        if(!in_array($folder, $folders_notempty))  // если убрать отрицание, то получится список полных папок
                  {
            $folders_empty[] = $folder;
                   echo $folder; echo '<br>'; // вывод списка пустых или полных папок
                   }
      }
}
Если у кого-то есть идеи, как побороть баг, то пишите пжл. Так же интересны и другие варианты, только желательно законченные.
Ну а тем, кто хотел бы мою функцию добавить удалением пустых папок приведу пример, где и чего нужно добавить:
PHP
1
2
function rem_empty($dir, $empty=true)  // естественно в начале функции
if ($empty) @rmdir($folder);  // в конце, после получения списка пустых папок
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
23.05.2019, 13:36
Помогаю со студенческими работами здесь

В поисках идеи по реализации
Всем привет, я - студент 1 курса, изучающий QT. Родилась идея не терять время и летом попрограть на QT. Решил написать 2048, но проблема...

Идеи для реализации
Доброго времени суток. Закралась идейка одна в голову. И хочется узнать есть ли возможность реализовать такое. Допустим есть...

Программа-тест - идеи реализации
Доброго времени суток. Я понимаю, что тема повторяется, но от части. Мне нужно написать программу-тест, при этом вопросы задаются в...

Программа-раскраска: идеи реализации
Как создать программу-раскраску в паскале? (просто хотя бы общую идею)

1С8 вопрос по реализации идеи
Идея такая - нужно сделать ЧТО-ТО (пока просто сам не могу понять отчет или документ с печатной формой, а может еще... не вижу больше...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru