27.11.2003, 10:02 | #1 |
Участник
|
WinApi. Удаление файлов глючит.
есть метод, который должен проверить каталог, на содержание txt файлов, и удалить их, в случае согласия пользователя.
В общем не пашет это дело - не хочет он удалять первый найденный файл, и зацикливается... Я так понимаю, из-за того что hanlom захватывает axapta этот файл и держит. WinApi::closeHandle(handle) и WinApi::findClose(handle); не помогают... Никто не подскажет, что я не так делаю? Спасибо. int deleteAllFiles() { int handle=0; str fn=''; DialogButton db; ; handle =conpeek(WinApi::findFirstFile(pathname+"\\*.txt"),1); if (handle != -1) { db = BOX::yesNo("В указанном каталоге уже есть TXT файлы!!! Удалить их?",DialogButton::Yes); if (db == DialogButton::Yes) { WinApi::closeHandle(handle); WinApi::findClose(handle); do { fn = conpeek(WinApi::findFirstFile(pathname+"\\*.txt"),2); handle =conpeek(WinApi::findFirstFile(pathname+"\\*.txt"),1); WinApi::deleteFile(pathname+'\\'+fn); } while (fn); } if (db == DialogButton::No) { return(0); } } return(1); } |
|
27.11.2003, 12:34 | #2 |
Дмитрий Ерин
|
Надо бы потестировать, жаль пока некогда...
Но навскидку, мне кажется, дело в многократном вызове FindFirstFile. Интуитивно чувствую, что нужно использовать вместо этого FindNextFile. Может, и ошибаюсь... |
|
27.11.2003, 14:59 | #3 |
Дмитрий Ерин
|
Вот рабочий код:
int deleteAllFiles() { int Handle=0; str FileName; str Path = 'D:\\Temp'; dialogButton Db; [Handle, FileName] = WinApi::findFirstFile(Path + '\\*.txt'); if (Handle == -1) return -1; // not found Db = BOX::yesNo("В указанном каталоге уже есть TXT файлы!!! Удалить их?", DialogButton::Yes); if (Db == DialogButton::No) return 0; while (FileName) { WinApi::deleteFile(Path + '\\' + FileName); FileName = WinApi::findNextFile(Handle); } WinApi::findClose(handle); return 1; } Ваши ошибки: 1. Как я и думал, нужно было использовать FindNextFile 2. Нельзя было выполнять WinApi::findClose(handle), не закончив операцию; 3. Использование не совсем традиционного способа вытаскивания значений из контейнера (conpeek) привело к повторному вызову функции FindFirstFile, что само по себе некорректно. Желаю удачи в нелегком деле удаления AllFiles с AllDrives PS: Ради интереса посмотрите реализацию класса CCCopyDirectory. |
|
|
За это сообщение автора поблагодарили: Gustav (5), alex55 (1), Logger (3). |
28.11.2003, 12:16 | #4 |
Участник
|
да чего-то тоже не пашет -((( - также захватывает файлы, и ничего не делает...
никто не поделится кодом, который просто чистит в заданном каталоге все txt файлы. спасибо. |
|
28.11.2003, 12:22 | #5 |
Дмитрий Ерин
|
Все пашет!
Если б не работало, я бы не послал этот постинг. Что-то у тебя с системой нелады... Может, дело в доступе к каталогу. Проверь права юзера, от имени которого запущена Аксапта. |
|
28.11.2003, 17:19 | #6 |
NavAx
|
Хочу добавить информацию по данной проблеме.
Перед тем как вызвать метод удаления файлов выполняется следующий код создания этих файлов : ... int i; str filename; ; for ( i=1; i<= conlen(files); i+=1) { if (! WinApi::fileExistsClient(conpeek(files,i))) WinAPI::createFile(conpeek(files,i)); } ... Далее идет запись в эти файлы. После этого при попытке удалить все файлы из каталога , возникает ошибка на файле , который создался первым. Все остальные удаляются. Если не создавать файлы при помощи кода указанного выше , данный метод удаления работает корректно. |
|
01.12.2003, 11:25 | #7 |
Дмитрий Ерин
|
Желательно после CreateFIle и работы с файлами закрывать их хандлеры, то есть использовать
WinAPI::closeHandle(handle); Кроме того, если запись в файлы осуществляется при помощи классов-наследников IO, то они тоже любят оставлять за собой файлы открытыми. Причем явно вызвать метод finalize() не получается. Зато в хелпе читаем: Цитата:
Close the file and, if data was written, flush the file buffers to disk. The object is normally finalized by leaving the scope so finalize is normally not called directly.
PHP код:
|
|
01.12.2003, 15:28 | #8 |
NavAx
|
Вот тестовый job-ик . В нем для простоты отсутствуют процедуры записи. Только создание и попытка удаления файлов. Почему возникает ошибка удаления ?
static void Testdf(Args _args) { container Files = ['1.txt', '2.txt', 'ABC.txt']; int Handle=0, i; str FileName; str Path = 'C:\\Temp\\'; dialogButton Db; int DelFileErrCode; ; for ( i=1; i<= conlen(files); i+=1) { if (! WinApi::fileExistsClient(Path+conpeek(files,i))) { WinAPI::createFile(Path+conpeek(files,i)); } } pause; [Handle, FileName] = WinApi::findFirstFile(Path + '*.txt'); if (Handle == -1) return; Db = BOX::yesNo(" В указанном каталоге существуют файлы. Удалить?",DialogButton::Yes); if (Db == DialogButton::Yes) { while (FileName) { WinApi::deleteFile(Path + FileName); DelFileErrCode = WinApi::deleteFile(Path + FileName); if (DelFileErrCode != 0) { box::info(' Ошибка № ' + int2str(DelFileErrCode) + ' при удалении файла ' + Path + FileName); } FileName = WinApi::findNextFile(Handle); } WinApi::findClose(handle); } } |
|
01.12.2003, 15:53 | #9 |
Участник
|
Ошибка возникает потому, что файл остается открытым после createFile.
|
|
01.12.2003, 16:05 | #10 |
Дмитрий Ерин
|
Опять те же грабли: не освобождаете после себя хандлеры. В приведенном коде добавим одну строчку в цикл создавания файлов:
PHP код:
Ну вот, пока писал, опередили... |
|
05.12.2003, 13:31 | #11 |
Участник
|
Большое спасибо. Всё заработало... -)
Просто аксапта почему-то намертво держала при создании только первый файл (а все отсальные удалялялись (если руками их удалять) ). Поэтому и начал искать грабли в процедуре удаления файлов. |
|