Russian Qt Forum

Qt => Общие вопросы => Тема начата: Андрей А. от Январь 24, 2007, 14:23



Название: Как обнаружить появление файла в папке?
Отправлено: Андрей А. от Январь 24, 2007, 14:23
Как обнаружить появление файла в папке средствами Qt или Windows API? Проблема в том, что отслеживаемых файлов может быть много и сделать это надо как можно быстрее, поэтому редкие опросы каталога не подойдут, а частые, боюсь, перегрузят прогу. Идеально бы подошло какое-нибудь системное сообщение Windows об этом, но таких вроде нет. Пробовал QfileSystemWatcher, но он отслеживает только удаление файлов и каталогов, к тому же делает это вроде как просто методои опроса с фиксированным интервалом.
Может кто-нибудь подскажет решение?


Название: Как обнаружить появление файла в папке?
Отправлено: Tonal от Январь 24, 2007, 14:25
QFileSystemWatcher?


Название: Как обнаружить появление файла в папке?
Отправлено: Андрей А. от Январь 24, 2007, 14:27
Цитата: "Tonal"
QFileSystemWatcher?

Я ж говорю - пробовал. Если только дописать этот класс. Но все равно это кривоватый метод.


Название: Как обнаружить появление файла в папке?
Отправлено: Tonal от Январь 24, 2007, 19:05
Для винды у троллей похоже ошибочка в коде.
Они используют системный вызов
Код:
FindFirstChangeNotification(
  LPCTSTR lpPathName,
  BOOL bWatchSubtree,
  DWORD dwNotifyFilter
)
где
Цитировать
lpPathName [in] Pointer to a null-terminated string that specifies the path of the directory to watch.

А они туда имя файла толкают...
Ну и флаги не соответственно не так выставляют...
Кстати если я всё правильно понял, то при указании директории для мониторинга, создание, удаление и переименование поддиректорий должно отслеживаться правильно.


Название: Как обнаружить появление файла в папке?
Отправлено: Андрей А. от Январь 24, 2007, 19:09
Цитата: "Tonal"
Кстати если я всё правильно понял, то при указании директории для мониторинга, создание, удаление и переименование поддиректорий должно отслеживаться правильно.

У меня не получалось. Отслеживается только переименование и удаление самого отслеживаемого каталога. :(


Название: Как обнаружить появление файла в папке?
Отправлено: mcgeenerman от Январь 24, 2007, 20:23
попробуй так
Код:
HANDLE s_eventHandles[2];
s_eventHandles[0] = m_eventHandle; // гдето в конструкторе m_eventHandle = CreateEvent(0,0,0,0); для <отмены>
s_eventHandles[1] = FindFirstChangeNotification(
(const char*)directory,FALSE,0L
|FILE_NOTIFY_CHANGE_FILE_NAME  
|FILE_NOTIFY_CHANGE_DIR_NAME  
// FILE_NOTIFY_CHANGE_ATTRIBUTES |
|FILE_NOTIFY_CHANGE_SIZE  
// FILE_NOTIFY_CHANGE_LAST_WRITE |
);
int ret=0;
while(1)
{
ret = WaitForMultipleObjects(2,s_eventHandles,FALSE,INFINITE);
if(ret==WAIT_OBJECT_0)
break; // terminate thread

if(!FindNextChangeNotification(eventHandles[1]))
break; // terminate thread

// для того чтобы понять какой файл был изменён или удалён необходим дополнительный алгоритм
}


для того чтобы понять какой файл был изменён или удалён я использовал метод сравнения содержимого каталога, тоесть читал весь каталог кидал наимнование в бинарное дерево контент1 (use std::set template class), после изменения содержимого (приведённый алгоритм) читал ещё раз в другое бинарное дерево контент2 и уже с ними манипулировал (выяснял разницу), далее запоменал изменённый контент1 контентом2 для следуещего раза. могу поделится классом если интересно пишите мыло.


Название: Как обнаружить появление файла в папке?
Отправлено: kotofay от Январь 25, 2007, 22:17
Цитата: "Tonal"
Для винды у троллей похоже ошибочка в коде.
Они используют системный вызов
Код:
FindFirstChangeNotification(
  LPCTSTR lpPathName,
  BOOL bWatchSubtree,
  DWORD dwNotifyFilter
)
где
Цитировать
lpPathName [in] Pointer to a null-terminated string that specifies the path of the directory to watch.

А они туда имя файла толкают...


Код:
 [Qt-4.2.0]
...
const QString absolutePath = fileInfo.absolutePath();
        HANDLE handle = handleForDir.value(absolutePath);
        if (!handle) {
            QT_WA({
                handle = FindFirstChangeNotificationW((TCHAR *) absolutePath.utf16(),

...


Это где это они имя толкают? :)

Цитата: "Tonal"
Ну и флаги не соответственно не так выставляют...
Кстати если я всё правильно понял, то при указании директории для мониторинга, создание, удаление и переименование поддиректорий должно отслеживаться правильно.


Да и с флагами там всё в порядке... Просто этот флаг (bWatchSubtree) не реализован судя по всему. Сама винда не реагирует на изменение в подкаталоге... Сам нарвался на это. Откорректировал QFileSystemWatcher, чтоб флажок этот туда передать, а он, зараза, не работает... :(


Название: Как обнаружить появление файла в папке?
Отправлено: mega_m от Январь 25, 2007, 23:02
Хм. забавно, меня тоже волнует этот вопрос. В файловых системах линукса всё просто, нужно только сравнить дату изменения текущего каталога. Но в винде это не работает :( .