![]() |
Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply |
![]() ![]() ![]() |
|
dma |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 31 Регистрация: 1.12.2006 Где: Belarus, Minsk Репутация: нет Всего: 1 |
Господа, помогите пожалуйста решить небольшой вопрос.
Заключается он в следующем: Есть директория, в которую время от времени "падают" файлы. Состояние директории отслеживается при помощи ReadDirectoryChanges, которая по приходу нового файла говорит FILE_ACTION_ADDED. Есть так же несколько потоков - обработчиков файлов из этой директории. Вообще говоря каждый поток должен брать и обрабатывать файл своей маски, но иногда возникает ситуация, когда несколько потоков берут один и тот же файл (к примеру для них была установлена одинакавая маска, но это не суть). Так вот собственно сам FILE_ACTION_ADDED говорит о том, что файл только создался, а т.к. файл может быть большим, потоку нужно дождаться пока он полностью скопируется. Я реализовал это следующим образом:
Таким образом получается, что когда файл скопируется, то какой-то из потоков его откроет на чтение, а остальные дальше будут ожидать освобождения файла, т.к. не смогут получить к нему доступ. Это хорошо ![]() Буду благодарен за любую помощь. Или за предложение лучшего варианта решения проблемы ![]() |
|||
|
||||
bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 21 Всего: 88 |
Вместо TFileStream используй THandleStream. Файл открывай апишкой CreateFile с флагом FILE_FLAG_DELETE_ON_CLOSE и без FILE_SHARE_DELETE
-------------------- Обижено школьников: 8 |
|||
|
||||
dma |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 31 Регистрация: 1.12.2006 Где: Belarus, Minsk Репутация: нет Всего: 1 |
ух ты! Спасибо! То что доктор прописал
![]() Вкратце, получилось так (поправьте, если ошибся):
Это сообщение отредактировал(а) dma - 1.3.2008, 13:19 |
|||
|
||||
bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 21 Всего: 88 |
1)убери sleep(10)
2)дескриптор окна и объекта ядра это разные вещи, поэтому вместо hwndF: HWND сделай hFile:THandle, хотя формально это не ошибка 3)FileExists убери. Вместо него в условие until добавь проверку, что если CreateFile вернула INVALID_HANDLE_VALUE, то все равно можно закончить цикл если GetLastError вернула ERROR_FILE_NOT_FOUND или ERROR_PATH_NOT_FOUND. Так и от break избавишся 4)добавь секцию try-finally-end, чтобы убедиться что файл будет закрыт, даже если после его открытия возникло исключение 5) ну и если файл существует но занят, то долбиться в него нужно не бесконечно, а до какого-то предела - вдруг тот кто занял подвис, это же не значит, что вслед за ним должен подвиснуть и ты за компанию. -------------------- Обижено школьников: 8 |
|||
|
||||
dma |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 31 Регистрация: 1.12.2006 Где: Belarus, Minsk Репутация: нет Всего: 1 |
Снова спасибо за подсказки!
![]() Есть пара вопросов: если Sleep убрать, то этот цикл забьёт весь процесор... а если их ещё и несколько будет, дык вообще вёсла.. в try finally естественно всё это поместиться, я здесь просто рабочий кусок рассматривал ![]() вобщем вышло что-то вроде этого:
кстати, а корректно ли вызывать GetLastError два раза в проверке условия, или же лучше в цикле один раз вызвать и запомнить значение в переменную? Это сообщение отредактировал(а) dma - 1.3.2008, 23:48 |
|||
|
||||
dma |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 31 Регистрация: 1.12.2006 Где: Belarus, Minsk Репутация: нет Всего: 1 |
По поводу GetLastErrorCode почитал мануал, сам себе отвечу: вроде как правильнее будет сохранить в переменную сразу после вызова CreateFile.
|
|||
|
||||
bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 21 Всего: 88 |
Файл занять чужим кодом или твоим? Добавлено через 2 минуты и 45 секунд как вариант сделать значительно более долгий слип - пару секунд -------------------- Обижено школьников: 8 |
|||
|
||||
dma |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 31 Регистрация: 1.12.2006 Где: Belarus, Minsk Репутация: нет Всего: 1 |
||||
|
||||
bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 21 Всего: 88 |
ну тогда проще длинный слип :(
-------------------- Обижено школьников: 8 |
|||
|
||||
Riply |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Комодератор Сообщений: 572 Регистрация: 27.3.2007 Где: St. Petersburg Репутация: 21 Всего: 32 |
Мне казалось, что использование потоков для работы с файлами, расположенными на одном диске, мякго говоря, - искуственное создание "тормозов". ![]() Я ошибаюсь ? P.S. Имеется ввиду именно работа, а не ожидание чего-то. |
|||
|
||||
Rennigth |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1708 Регистрация: 21.6.2004 Где: Moscow Репутация: 8 Всего: 76 |
ну я думаю если реализация с несколькоми(разными) потоками сделана только из-за того что они должны выполнять разные действия с файлами, но паралельное использование нечастое/исключенное, то нормуль ![]() -------------------- (* Honesta mors turpi vita potior *) |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: WinAPI и системное программирование" | |
|
Запрещено: 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |