|
|
|
| Доброго времени суток всем!
Подскажите, плиз, как проще всего получить листинг каталога со всеми вложенными каталогами и файлами+размер и время создания+ записать в текстовый файл.
В книге подробно описано получение списка файлов в директории. А как организовать обход дерева? | |
|
|
|
|
|
|
|
для: denvor
(24.01.2005 в 00:26)
| | Когда вы получили листинг директории, то проверяете не является ли полученный элемент каталогом. Если является, то вызываете ту же самую функцию для этого элемента (каталога). Таким образом, обойдете все дерево. | |
|
|
|
|
|
|
|
для: denvor
(24.01.2005 в 00:26)
| | Обычно для этого используется рекурсивная функция обхода... вообще когда имеется дерево - следует использовать рекурсивный спуск - это единственная задача где по настоящему нужна рекурсия.
Попробуйте запусить скрипт (только не в корне диска С :)))
<?php
scan_dir(".");
//////////////////////////////////////////////////////////
// Рекурсивная функция - спускаемся вниз по каталогу
//////////////////////////////////////////////////////////
function scan_dir($dirname)
{
// Открываем текущую директорию
$dir = opendir($dirname);
// Читаем в цикле директорию
while (($file = readdir($dir)) !== false)
{
// Если файл обрабатываем его содержимое
if($file != "." && $file != "..")
{
// Если имеем дело с файлом - регистрируем его
if(is_file($dirname."/".$file))
{
echo $dirname."/".$file." - ".
date("m.d.y",filemtime($dirname."/".$file))." - ".
filesize($dirname."/".$file)."<br>";
}
// Если перед нами директория, вызываем рекурсивно
// функцию scan_dir
if(is_dir($dirname."/".$file))
{
echo $dirname."/".$file."<br>";
scan_dir($dirname."/".$file,$fd,$fb);
}
}
}
// Закрываем директорию
closedir($dir);
}
?>
|
| |
|
|
|
|
|
|
|
для: cheops
(24.01.2005 в 00:40)
| | Волшебство! Оно работает!
Правда, я попробовал в файл записать:
// создаем пустой файл для записи
$file = fopen("check_new.txt", "w+");
...
...
$str = $dirname."/".$file." - ". date("m.d.y",filemtime($dirname."/".$file))." - ".filesize($dirname."/".$file);
fputs ($file, $str);
|
Файл создается, но в него ничего не пишется:
Warning: fputs(): supplied argument is not a valid stream resource in w:\home\127.0.0.1\www\list1.php on line 31
Что не так? | |
|
|
|
|
|
|
|
для: denvor
(24.01.2005 в 13:36)
| | Похоже пустой идентификатор файла $file.
Вы уверены, что он нигде не затирается в коде? | |
|
|
|
|
|
|
|
для: glsv (Дизайнер)
(24.01.2005 в 14:48)
| | Точно, перезаписывается, но... Поменял на $file1 - то же самое. Чтобы не гадать - вот весь код (это код cheops'a в модификации для записи в файл):
<?php
$file1 = fopen("check_new.txt", "w+"); //создаем файл
scan_dir(".");
//////////////////////////////////////////////////////////
// Рекурсивная функция - спускаемся вниз по каталогу
//////////////////////////////////////////////////////////
function scan_dir($dirname)
{
// Открываем текущую директорию
$dir = opendir($dirname);
// Читаем в цикле директорию
while (($file = readdir($dir)) !== false)
{
// Если файл обрабатываем его содержимое
if($file != "." && $file != "..")
{
// Если имеем дело с файлом - регистрируем его
if(is_file($dirname."/".$file))
{
$str = $dirname."/".$file." - ". date("m.d.y",filemtime($dirname."/".$file))." - ".filesize($dirname."/".$file);
fputs ($file1, $str); //пишем в файл
}
// Если перед нами директория, вызываем рекурсивно
// функцию scan_dir
if(is_dir($dirname."/".$file))
{
$str = $dirname."/".$file;
fputs ($file1, $str); //снова пишем в файл
scan_dir($dirname."/".$file,$fd,$fb);
}
}
}
// Закрываем директорию
closedir($dir);
}
fclose ($file1); //закрываем файл
?>
|
| |
|
|
|
|
|
|
|
для: denvor
(24.01.2005 в 17:05)
| | Немного переделал - теперь файл для записи открывается непосредственно перед записью. Все заработало. Теперь появилиь такие вопросы:
- как вставить перенос на новую строку
- это наверное, неправильно открывать файл в цикле, не будет ли это медленно работать?
- в связи с этим: как писать эти данные в массив с тем, чтобы потом один раз записать массив в файл? | |
|
|
|
|
автор: cheops (из ННГУ) (24.01.2005 в 18:36) |
|
|
для: denvor
(24.01.2005 в 18:10)
| | 1) Для перевода строки следует добавить последовательность \n
<?php
echo ""Слово\n";
?>
|
2) Да, так делать не стоит в предыдущем листинге следует просто передать дескриптор открытого файла $file1 в качестве параметра функции.
3) Массив следует объявить в функции с атрибутом GLOBAL
<?php
GLOBAL $arr;
$arr = array();
?>
|
В этом случае результаты будут сохранятся после выхода из функции. Массив для удобства лучше упаковать в строку как это описывается по ссылке
http://www.softtime.ru/forum/read.php?id_forum=1&id_theme=907 | |
|
|
|
|
|
|
|
для: cheops (из ННГУ)
(24.01.2005 в 18:36)
| | "...передать дескриптор открытого файла $file1 в качестве параметра функции."
это вот так?
function scan_dir($dirname, $file1)
|
| |
|
|
|
|
|
|
|
для: denvor
(07.02.2005 в 23:16)
| | да. | |
|
|
|
|
|
|
|
для: cheops (из ННГУ)
(24.01.2005 в 18:36)
| | И сразу еще вопрос: полученный листинг нужно сравнить с предыдущем - как это правильнее сделать сравнивать массивы или файлы? | |
|
|
|
|
|
|
|
для: denvor
(07.02.2005 в 23:18)
| | Если версия PHP >= 4.3.0, то можно использовать для получения листинга следующий скрипт:
<?php
echo "<pre>";
print_r(glob("/home/myfiles/*.*"));
?>
|
Кроме того можно использовать:
<?php
echo "<pre>";
print_r(glob("/home/myfiles/*/*.{php,txt}", GLOB_BRACE));
?>
|
Это выведет все файлы с расширением php или txt из /home/myfiles/ и из папок которые находятся в /home/myfiles/. | |
|
|
|
|
|
|
|
для: isset
(07.02.2005 в 23:26)
| | Здорово!
А как прикрутить туда вывод размера и даты изменения файла? В справочнике на сайте я не нашел эту функцию :( | |
|
|
|
|
|
|
|
для: denvor
(08.02.2005 в 00:24)
| | Для определения размера файла предназначена функция filesize(), принимающая в качестве единственного параметра путь к файлу и возвращает размер файла в байтах. http://www.softtime.ru/dic/id_dic=184&id_group=6
Для определения даты последнего изменения файла, предназначена функция filectime() http://www.softtime.ru/dic/id_dic=178&id_group=6 | |
|
|
|
|
|
|
|
для: cheops
(08.02.2005 в 00:31)
| | 2 cheops: с кодом isset все получилось - прогнал массив, прикручивая к файлам время и дату и запихивая обратно в массив. Но! Все равно нужно делать рекурсивный обход дерева - так что ваш код для моих целей больше подходит. Я попробовал в ваш код вставить вместо вывода листинга на экран вывод его в массив, с тем, чтобы за пределами функции дальше работать с эти массивом, но ниего не вышло - за пределы функции массив не передается даже при объявлении GLOBAL (global ... я вставил сразу после первой фигурной скобки). | |
|
|
|
|
|
|
|
для: denvor
(08.02.2005 в 21:10)
| | Хм... не должно бы быть так, приведите пожалуйста конечный код... может я чего свежим взглядом замечу... | |
|
|
|
|
|
|
|
для: cheops
(08.02.2005 в 22:56)
| | Доброго времени суток, cheops и All!
Вот код:
как сделать правильно и в чем проблема -не знаю. Если ставлю echo $arr[2]; перед последней фигурной скобкой - выводит значение, а после функции - нет :(
<?php
scan_dir(".");
function scan_dir($dirname)
{
GLOBAL $arr;
$arr = array();
// Открываем текущую директорию
$dir = opendir($dirname);
// Читаем в цикле директорию
while (($file = readdir($dir)) !== false)
{
// Если файл обрабатываем его содержимое
if($file != "." && $file != "..")
{
// Если имеем дело с файлом - регистрируем его
if(is_file($dirname."/".$file))
{
$arr[] = $dirname."/".$file." - ".date("m.d.y",filemtime($dirname."/".$file))." - ".filesize($dirname."/".$file)."<br>";
}
// Если перед нами директория, вызываем рекурсивно
// функцию scan_dir
if(is_dir($dirname."/".$file))
{
$arr[] = $dirname."/".$file."<br>";
scan_dir($dirname."/".$file,$fd,$fb);
}
}
}
// Закрываем директорию
closedir($dir);
}
// посмотрим третий элемент массива, к примеру...
echo ($arr[2]);
?>
|
| |
|
|
|
|
|
|
|
для: denvor
(10.02.2005 в 00:44)
| | Хм... а уменя такой вариант всё выводит... какая версия PHP? | |
|
|
|
|
|
|
|
для: cheops
(10.02.2005 в 09:49)
| | Да, действительно работает. Теперь я после последней фигурной скобки вставляю
foreach($arr as $val)
{
echo("$val");
}
|
Выводит только файлы (без директорий) в текущей директории и ошибку:
Undefined variable: fb in w:\home\127.0.0.1\www\list2.php on line 27
Вот. | |
|
|
|
|
|
|
|
для: denvor
(10.02.2005 в 14:19)
| | Хм... дело в том, что здесь происходит рекурсивный вызов и если изменяется число параметров в исходной функции - нужно изменить число и в вызове (я гляжу это забы сделать :), поэтому исправьте пожалуйста строку
<?php
scan_dir($dirname."/".$file,$fd,$fb);
?>
|
на
<?php
scan_dir($dirname."/".$file);
?>
|
| |
|
|
|
|
|
|
|
для: cheops
(10.02.2005 в 22:46)
| | я так и подумал :)
Теперь ошибки нет, но по -прежнему выводит только файлы текущей директории.
Причем, для проверки я оставил вывод на экран - все нормально работает. Проблема , похоже, в рекурсии - там то ли не идет запись в массив, то ли он затирается внешним циклом, когда регистрируются файлы текущей директории. Что тут можно придумать? | |
|
|
|
|
|
|
|
для: denvor
(11.02.2005 в 17:07)
| | Отвечаю сам себе :):
Явно определяя переменную $arr как массив, мы обнуляем ее каждый раз при рекурсивном обращении. Убираем строчку $arr = array (); - все работает.
Всем большое спасибо! | |
|
|
|