Russian Qt Forum
Ноябрь 23, 2024, 12:16 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: JulyScanDir - класс рекурсивного поиска файлов в отдельном потоке  (Прочитано 13645 раз)
IGHOR
Крякер
****
Offline Offline

Сообщений: 390



Просмотр профиля WWW
« : Август 07, 2009, 00:48 »

Я написал универсальный класс для поиска файлов в папках JulyScanDir.
Используя его можно сделать прогрессбар перебора файлов или что-то другое не нагружая основной поток

Пример использования запуска с одной строки параметров:
Код:
JulyScanDir *scanDir = new JulyScanDir(this);
             scanDir->scanDir("C:\\Films","*.avi");  // задание параметров поиска и запуск

Пример использования запуска с отдельными параметрами:
Код:
JulyScanDir *scanDir = new JulyScanDir(this);
             scanDir->setStartDir("C:\\Films"); // задает папку или список папок разделенных ;; или через QStringList
             scanDir->setSearchSubFolders(false); // ищем файлы только в одной папке
             scanDir->setSubFoldersFirst(true);   // класс в текущей директории сначала сканирует папки а потом файлы
QStringList  filtersList;
             filtersList << "*.avi" << "*.mpg";   // задание маски файлов
             scanDir->setFilesFilter(filtersList);
             scanDir->scanDir();                // запуск поиска

В ответ получаем сигналы которые можно прикрутить к переменной класса:
Код:
void dirChanged(QString);      // Во время поиска возвращает полный адрес следующей директории
void fileChanged(QString);     // Во время поиска возвращает полный адрес текущего файла
void fileChanged(QFileInfo);   // Во время поиска возвращает полную информацию о файле
void numChanged(int);          // Во время поиска возвращает последовательный номер найденого файла
void loadedList(QStringList);  // По завершению поиска возвращает список найденых файлов
void errorHeppend(int);        // Если случилась ошибка то возвращает: 0 если не найдено никаких файлов
                               // и 1 если заданая папка поиска не существует

При начале сканирования и по окончании fileChanged возвращает пустую строку (так удобнее при перерисовке результата)

Добавлено:
Код:
void setIgnoreDirs(QStringList); // задает список полных адресов папок что будут пропущены в поиске
void setIgnoreDirs(QString); // задает одну папку что будет пропущена в поиске или список папок через ;;
void clearIgnoreDirs(); // очищает и отключает список игнорируемых папок
void setRegExp(QRegExp fileRegExp); // задание регулярного выражения, если оно верно к имени файла он будет выведен в результате, в противном случае пропущен
void clearRegExp();  // очищает и отключает RegExp
void setScanHidden(bool hidden); // задает фильтр поиска, искать ли скрытые файлы и папки

setStartDir(), setIgnoreDirs(), setFilesFilter() задаються как QStringList так и QString.
QString будет разбит на список разделенный ;;

Надеюсь услышать критику, отзывы о работе и помощь в улучшении класса

Прикрепленная в файлах версия класса: v1.25
« Последнее редактирование: Август 14, 2009, 01:21 от IGHOR » Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #1 : Август 07, 2009, 06:19 »

> scanDir->setSearchSubFolders(false); // ищем файлы только в одной папке
Сделай еще уровень рекурсии.
> void fileChanged(QString)
Еще добавь fileChanged(QFileInfo)

Регекспы поддерживает?
===============================
Убери банер в подписи.
Еще нужно scanDir->setStartDirs(QStringList()) и scanDir->setIgnoreDirs(QStringList())
« Последнее редактирование: Август 07, 2009, 11:30 от panter_dsd » Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
IGHOR
Крякер
****
Offline Offline

Сообщений: 390



Просмотр профиля WWW
« Ответ #2 : Август 07, 2009, 13:35 »

scanDir->setSearchSubFolders(false); заменю на scanDir->setSubFoldersLevel(int);
добавлю void fileChanged(QFileInfo),
> Еще нужно scanDir->setStartDirs(QStringList()) и scanDir->setIgnoreDirs(QStringList())
ето мне понравилось, постараюсь сегодня ето дописать.
А с регекспами ето для чего? Для поиска имен файлов по маске?
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #3 : Август 07, 2009, 17:44 »

Угу. Регекспы бывают очень необходимы.
Нужно будет дополнить поиском по атрибутам(время, дата, и т.п.) и сохранением поисковых запросов, если конечно захочешь. Если что, обращайся, мне все равно такое нужно в PantherCommander, так что можем твой вариант довести до ума и я его себе включу. Если, конечно, будешь не против. Подмигивающий
« Последнее редактирование: Август 07, 2009, 17:47 от panter_dsd » Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
IGHOR
Крякер
****
Offline Offline

Сообщений: 390



Просмотр профиля WWW
« Ответ #4 : Август 07, 2009, 19:02 »

panter_dsd, с регекспами я ещё не пробовал ничего, буду рад помощи в до-писании класса,
сохранение поисковых запросов думаю ето дело проги к которой подключается класс,
а сам класс должен только прошвырнуться по файлах и возвращать их свойства на все случаи жизни.
И конечно я не против чтобы вы использовали его в PantherCommander, заодно будет возможность его хорошо протестировать.
Думаю многим Qt программерам пригодиться этот класс, буду рад комментариям от тестеров класса.
« Последнее редактирование: Август 07, 2009, 19:05 от IGHOR » Записан
IGHOR
Крякер
****
Offline Offline

Сообщений: 390



Просмотр профиля WWW
« Ответ #5 : Август 08, 2009, 01:05 »

Файлы обновил. Тестируйте. Глубину рекурсии потом допишу, когда обдумаю насколько оно нужно и в чем может применяться.
« Последнее редактирование: Август 08, 2009, 04:31 от IGHOR » Записан
IGHOR
Крякер
****
Offline Offline

Сообщений: 390



Просмотр профиля WWW
« Ответ #6 : Октябрь 07, 2009, 21:10 »

Кто еще пробовал? Все работает хорошо?
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #7 : Октябрь 07, 2009, 21:55 »

Глубину рекурсии потом допишу, когда обдумаю насколько оно нужно и в чем может применяться.

Рекурсия ненужна. Можно обойтись и без нее, при помощи листа:

Код
C++ (Qt)
QFileInfoList dirs;
dirs << QFileInfo( path );
while ( !dirs.isEmpty() )
{
 
 QFileInfo dirInfo = dirs.takeFirst();
 for ( QListIterator<QFileInfo> it( QDir( dirInfo.path() ).entryInfoList( flags ) ); it.hasNext(); )
 {
   const QFileInfo & newDirInfo = it.next();
   // handle it
   dirs << newDirInfo;
 }
}

Также обрати внимание на QDirIterator
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
IGHOR
Крякер
****
Offline Offline

Сообщений: 390



Просмотр профиля WWW
« Ответ #8 : Октябрь 08, 2009, 19:39 »

pastor, очень спасибо
изучу QFileInfoList и QDirIterator
так же проверю производительность двух вариантов и отпишусь о результатах
Записан
CProger
Гость
« Ответ #9 : Апрель 03, 2010, 21:21 »

pastor
Вы не подскажите почему у меня не работает Ваш код?
Я вот так его подызменил (на месте flags):
Код
C++ (Qt)
QFileInfoList dirs;
dirs << QFileInfo( "." );
 
while ( !dirs.isEmpty() ) {
 
QFileInfo dirInfo = dirs.takeFirst();
 
for ( QListIterator<QFileInfo> it( QDir( dirInfo.path() ).entryInfoList( QDir::NoDotAndDotDot ) ); it.hasNext(); ) {
 
const QFileInfo & newDirInfo = it.next();
dirs << newDirInfo;
 
}
}
 

но вот на это ругается (gcc):
Код:
main.cpp: In member function ‘void MyClass::MyFunc()’:
main.cpp:46: ошибка: invalid use of incomplete type ‘struct QDir’
/usr/include/qt4/QtCore/qfileinfo.h:55: ошибка: forward declaration of ‘struct QDir’
main.cpp:46: ошибка: неполный тип ‘QDir’ использован во вложенном спецификаторе имени
make: *** [main.o] Ошибка 1
смущает вот эта ошибка: "forward declaration of ‘struct QDir’". Посмотрел документацию к этой функции.. да вроде ничего плохого...))
« Последнее редактирование: Апрель 03, 2010, 21:25 от CProger » Записан
niXman
Гость
« Ответ #10 : Апрель 03, 2010, 22:21 »

Цитировать
Посмотрел документацию к этой функции
это класс.

Цитировать
почему у меня не работает Ваш код?
#include <QtCore/QDir>
Записан
CProger
Гость
« Ответ #11 : Апрель 03, 2010, 22:57 »

Точно! Спасибо!

Код заработал, сейчас он такой у меня. Но знаете.. он почему-то зацикливается Улыбающийся Он выводит в цикле все имена файлов текущей директории и так до бесконечности.. т.е. чередуются имён пять файлов) Не знаете почему такое может быть?
Код
C++ (Qt)
QFileInfoList dirs;
 
dirs << QFileInfo( "." );
 
while ( !dirs.isEmpty() ) {
 
QFileInfo dirInfo = dirs.takeFirst();
 
for ( QListIterator<QFileInfo> it( QDir( dirInfo.path() ).entryInfoList( QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files ) ); it.hasNext(); ) {
 
const QFileInfo &newDirInfo = it.next();
dirs << newDirInfo;
 
printf( "%s\n", newDirInfo.absoluteFilePath().toAscii().constData() );
 
}
 
}
 
Записан
Kolobok
Гость
« Ответ #12 : Апрель 03, 2010, 23:40 »

Код:
while ( !dirs.isEmpty() )

Чего ты хотел добиться этой строчкой?
Записан
CProger
Гость
« Ответ #13 : Апрель 03, 2010, 23:45 »

Код:
while ( !dirs.isEmpty() )

Чего ты хотел добиться этой строчкой?
а я и не подумал над этой строчкой, скопировал вышеприведённый код. Подумал.. ну видимо цикл продолжается до тех пор пока список директорий не пуст. Как только пуст, так я понимаю - завершиться должен.. но не завершается.. Улыбающийся
Записан
niXman
Гость
« Ответ #14 : Апрель 04, 2010, 00:49 »

вообще-то, тот код, какой-то мудреный.
Код
C++ (Qt)
void ScanDir(const QString& path) {
QDirIterator it(path,
QDir::Files|QDir::Dirs|QDir::NoDotAndDotDot,
QDirIterator::Subdirectories
);
while ( it.hasNext() ) {
QFileInfo fi = it.fileInfo();
               ...
it.next();
}
}
 
 
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.191 секунд. Запросов: 23.