Проблема с циклом FindFirstFile/FindNextFile
От: Pumpr  
Дата: 17.10.02 13:03
Оценка:
Я программирую под Builder С++ 6.0.

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

Еще есть служебный поток (порожденный от TThread), который через функцию TThread::Synchronize и цикл FindFirstFile/FindNextFile выбирает их оттуда и обрабатывает. Так вот он не всегда цепляет файлы в той последовательности, в которой их подсовывает главный поток. Это заметно когда файлов много и идут они быстро один за другим. Если отправлять файлы по одному, то все нормально.

Кстати я еще замечал интересную фишку. Если в дебаге отлаживаеть цикл FindFirstFile/FindNextFile и в какой-то момент приостановив прогу, выйдти в Far и грохнуть все выбираемые файлы этого каталога, то при возвращении в дебуг в цикле будут цепляться несуществующие файлы!
Это я заметил довольно давно.

Может перед циклом FindFirst/FindNext или где-то внутри него как-то рефрешить информацию о перебираемых файлах, ведь не зря же есть ф-ия SHChangeNotify, которая уведомляет систему об изменениях в файловой системе.

Кто-нибудь знает, как вообще перебирает файлы цикл FindFirstFile/FindNextFile, т.е. в какой последовательности ?

Мне видится,что проблема в следующем. Есть общий каталог, куда кто-то пишет и кто-то читает, так вот порядок записи должен совпадать с порядком считывания.

Как нужно формировать файлы в общем каталоге, чтобы они потом считывались в порядке создания ? И как считывать их правильно ?

У меня сейчас сделано так. Главный поток создает файл в темповом каталоге, затем в общем каталоге создается файл по CreateFile с эксклюзиывным доступом, куда переписывается информация из темпового файла и делается CloseHandle.

Поток выборки использует цикл FindFirstFile/FindNextFile, в котором для каждого найденного файла проверяет эксклюзивный доступ к нему. Если доступа нет — FindClose и цикл начинается сначала.
Re: Проблема с циклом FindFirstFile/FindNextFile
От: Patalog Россия  
Дата: 17.10.02 13:07
Оценка:
Здравствуйте Pumpr, Вы писали:

[]

В твоей ситуации я бы посоветовал FindFirstChangeNotification\FindNextChangeNotification\FindCloseChangeNotification

P>Кто-нибудь знает, как вообще перебирает файлы цикл FindFirstFile/FindNextFile, т.е. в какой последовательности ?


Имхо, на FAT перебирает в том порядке, в котором они идут в таблице, т.е. в той самой FAT

[]
Почетный кавалер ордена Совка.
Re: Проблема с циклом FindFirstFile/FindNextFile
От: SergH Россия  
Дата: 17.10.02 13:14
Оценка:
Здравствуйте Pumpr, Вы писали:

P>Я программирую под Builder С++ 6.0.


P>У меня главный поток приложения по нажатию кнопки сначала создает файл для отправки в темповом каталоге, а затем перебрасывае его в общий выходной каталог. И так сразу для нескольких файлов.


P>Еще есть служебный поток (порожденный от TThread), который через функцию TThread::Synchronize и цикл FindFirstFile/FindNextFile выбирает их оттуда и обрабатывает. Так вот он не всегда цепляет файлы в той последовательности, в которой их подсовывает главный поток. Это заметно когда файлов много и идут они быстро один за другим. Если отправлять файлы по одному, то все нормально.


P>Кстати я еще замечал интересную фишку. Если в дебаге отлаживаеть цикл FindFirstFile/FindNextFile и в какой-то момент приостановив прогу, выйдти в Far и грохнуть все выбираемые файлы этого каталога, то при возвращении в дебуг в цикле будут цепляться несуществующие файлы!

P>Это я заметил довольно давно.

Интерестно.. Попробую, т.к. сомневаюсь.. Это несколько противоречит тому, что я думал. Под какими ОС наблюдается?

P>Может перед циклом FindFirst/FindNext или где-то внутри него как-то рефрешить информацию о перебираемых файлах, ведь не зря же есть ф-ия SHChangeNotify, которая уведомляет систему об изменениях в файловой системе.


P>Кто-нибудь знает, как вообще перебирает файлы цикл FindFirstFile/FindNextFile, т.е. в какой последовательности ?


Наверное, в той, в которой они в файловой системе.

P>Мне видится,что проблема в следующем. Есть общий каталог, куда кто-то пишет и кто-то читает, так вот порядок записи должен совпадать с порядком считывания.


P>Как нужно формировать файлы в общем каталоге, чтобы они потом считывались в порядке создания ? И как считывать их правильно ?


Использовать какой-то внешний признак. Например, имя файла или время создания. Т.е. сначала получить весь список, а потом его сортировать.

P>У меня сейчас сделано так. Главный поток создает файл в темповом каталоге, затем в общем каталоге создается файл по CreateFile с эксклюзиывным доступом, куда переписывается информация из темпового файла и делается CloseHandle.


P>Поток выборки использует цикл FindFirstFile/FindNextFile, в котором для каждого найденного файла проверяет эксклюзивный доступ к нему. Если доступа нет — FindClose и цикл начинается сначала.


Эти потоки в одном приложении? Тогда что мешает им общаться между собой? Т.е. "главный" сформировал файл и пинает рабочий.. В процессе "пинания" можно передавать имя. А можно вообще без файлов, сразу передавать данные..
Делай что должно, и будь что будет
Re[2]: Проблема с циклом FindFirstFile/FindNextFile
От: Pumpr  
Дата: 17.10.02 13:31
Оценка: 8 (1)
Здравствуйте SergH, Вы писали:

P>>Кстати я еще замечал интересную фишку. Если в дебаге отлаживаеть цикл FindFirstFile/FindNextFile и в какой-то момент приостановив прогу, выйдти в Far и грохнуть все выбираемые файлы этого каталога, то при возвращении в дебуг в цикле будут цепляться несуществующие файлы!

SH>Интерестно.. Попробую, т.к. сомневаюсь.. Это несколько противоречит тому, что я думал. Под какими ОС наблюдается?


Под Win2000 железно так работает. Только что проверил, до этого работал на Win98 там тоже так было.
Как это сделать. Под дебагом делаем цикл FindFirstFile/FindNextFile и ставим точку прерывания на то мнесто где находится файл. Копируем откуда-нибудь в этот каталог штук 10 файлов. Получаем остановку. Переходим в Far и удаляем все файлы, кроме найденного. После этого у меня очередной цикл FindNextFile находит файл, которого уже нет. Правда только один, но какая разница ?

P>>У меня сейчас сделано так...

SH>Эти потоки в одном приложении? Тогда что мешает им общаться между собой? Т.е. "главный" сформировал файл и пинает рабочий.. В процессе "пинания" можно передавать имя. А можно вообще без файлов, сразу передавать данные..

У меня в одном, но у нас взаимодействуют 2 приложения и мы всегдла полагались на непогрешимость FindFirstFile/FindNextFile в плане последовательности файлов.
Re[2]: Проблема с циклом FindFirstFile/FindNextFile
От: Pumpr  
Дата: 17.10.02 13:36
Оценка:
Здравствуйте Patalog, Вы писали:


P>В твоей ситуации я бы посоветовал FindFirstChangeNotification\FindNextChangeNotification\FindCloseChangeNotification


Очень интересно, надо попробовать. Говорят, что были случаи когда файл в каталоге был, а эта связка его не замечала — такое может быть и как с этим бороться ?

И еще. Конструкция FindFirstChangeNotification\FindNextChangeNotification находит файлы в каталоге, если они уже есть ? Т.е. не появились во время работы этих функций, а существовали на диске.


P>>Кто-нибудь знает, как вообще перебирает файлы цикл FindFirstFile/FindNextFile, т.е. в какой последовательности ?


P>Имхо, на FAT перебирает в том порядке, в котором они идут в таблице, т.е. в той самой FAT


Вот и я так думаю.
Re[3]: Проблема с циклом FindFirstFile/FindNextFile
От: SergH Россия  
Дата: 17.10.02 13:41
Оценка:
Здравствуйте Pumpr, Вы писали:

P>Под Win2000 железно так работает. Только что проверил, до этого работал на Win98 там тоже так было.

P>Как это сделать. Под дебагом делаем цикл FindFirstFile/FindNextFile и ставим точку прерывания на то мнесто где находится файл. Копируем откуда-нибудь в этот каталог штук 10 файлов. Получаем остановку. Переходим в Far и удаляем все файлы, кроме найденного. После этого у меня очередной цикл FindNextFile находит файл, которого уже нет. Правда только один, но какая разница ?

Спасибо за подробное описание, попробую.

P>У меня в одном, но у нас взаимодействуют 2 приложения и мы всегдла полагались на непогрешимость FindFirstFile/FindNextFile в плане последовательности файлов.


Тогда можно так:

1. Рабочий поток крутит следующий цикл:
a) FindFirstFile/FindNextFile для обнаружения всех файлов
b) Как советовал Patalog, ожидание FindNextChangeNotification, когда дождались — goto a)

2. Главный поток делает задержки между отправкой файлов. Я думаю, Sleep(1000) хватит за глаза.
Делай что должно, и будь что будет
Re: Проблема с циклом FindFirstFile/FindNextFile
От: _Dinosaur Россия  
Дата: 17.10.02 14:37
Оценка:
Здравствуйте Pumpr.

Я думаю, что в Вашем случае лучше отказаться от использования FindFirstFile и FindNextFile.

Взаимодействие между потоками можно организовать следующим образом:
— Если нет острой необходимости в использовании файлов, от них лучше отказаться (производительность++)
— Поток А — формирующий данные; поток Б — их принимающий.
1. Поток Б — содержит очередь данных, подлежащих обработке, в кольцевом списке.
(в случае с файлами — имена файлов, если без них — указатели)
2. Поток Б — должен иметь функции работы с очередью; указатель на начало очереди; указатель на конец очереди.
3. Поток А после подготовки данных (записи их в файл) помещает в очередь потока Б указатель на эти данные (имя файла).
4. Поток Б получает данные из очереди и обрабатывает их.

Думаю, что это поможет.
Завидую людям, которые могут себе позволить никуда не спешить.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.