Автор | Сообщение |
|
| |
Пост N: 681
Зарегистрирован: 08.07.06
|
|
Отправлено: 11.11.22 14:07. Заголовок: FOPEN() -> FWRITE() -> FCLOSE()
Добрый день Есть у меня стандартный алгоритм, который открывает файл на запись и кусочками через FWRITE() с красивым прогресс-баром записывает его, после чего закрывает. Столкнулся с тем, что при записи на USB флэшки и/или некоторые ресурсы с медленным доступом прогресс почти мгновенно добегает до 100%, после чего доооолго висит на отработке команды FCLOSE(). Понятное дело, что это кэш Windows. Как-бы пофиксить такое поведение ? То есть нужна какая-то команда после FWRITE(), (по аналогии с базой данных - DBCOMMIT()) которая дожидалась бы окончания процесса физической записи на носитель, после чего брался-бы следующий кусок и тд.
|
|
|
Ответов - 12
[только новые]
|
|
|
| |
Пост N: 7720
Зарегистрирован: 17.05.05
|
|
Отправлено: 11.11.22 16:19. Заголовок: Попробуй вместо FOPE..
Попробуй вместо FOPEN() -> FWRITE() -> FCLOSE() HB_VFOPEN() -> HB_VFWRITE() -> HB_VFCLOSE() Возможно результат будет иным.
|
|
|
|
| постоянный участник
|
Пост N: 4177
Зарегистрирован: 17.02.12
|
|
Отправлено: 11.11.22 16:51. Заголовок: Делаю добавку к max ..
Делаю добавку к max счетчику ~ 1/3 - 1/5 от значения для индикации, т.е. не довожу до конца бегунка весь процесс копирования (один файл или несколько их или расчета по алгоритмам) и потом, выйдя из цикла (можно подержать паузу тут из ini), довожу бегунок до конца с интервалом от 0.1 - 0.7 сек. (по умолчанию 0.5). Потом вывожу текст о завершении или статистика и подвешиваю ~3-5 сек.
|
|
|
|
| |
Пост N: 7721
Зарегистрирован: 17.05.05
|
|
Отправлено: 11.11.22 17:03. Заголовок: Sergy пишет: с кра..
Sergy пишет: цитата: | с красивым прогресс-баром |
| Покажи картинку
|
|
|
|
| Администратор
|
Пост N: 4094
Зарегистрирован: 23.05.05
|
|
Отправлено: 11.11.22 18:28. Заголовок: Наблюдал подобное пр..
Наблюдал подобное при копировании файлов фаром на флешку. У него свой прогресс-бар. Может быть такой эффект дает антивирус
|
|
|
|
| |
Пост N: 7722
Зарегистрирован: 17.05.05
|
|
Отправлено: 11.11.22 18:40. Заголовок: Pasha пишет: Наблюд..
Pasha пишет: цитата: | Наблюдал подобное при копировании файлов фаром на флешку |
| Тоже происходит и при копировании файлов на USB винт.
|
|
|
|
| постоянный участник
|
Пост N: 4178
Зарегистрирован: 17.02.12
|
|
Отправлено: 11.11.22 19:58. Заголовок: SergKis пишет Делаю ..
SergKis пишет цитата: | Делаю добавку к max счетчику ~ ... |
| Другой вариант для бегунка исп. таймер (при достижении max, начинать с начала счетчик бегунка, если надо). В функцию такого бегунка передаю блок кода, счетчик max, шаг и заголовок окна. Ф-я не большая (МиниГуи), как есть, чисто для инфы Скрытый текст
*-----------------------------------------------------------------------------* FUNCTION Do_WaitWindow( bBlk, nMax, nStep, cCapt ) *-----------------------------------------------------------------------------* LOCAL nY := GetBorderHeight() LOCAL nX := GetBorderWidth() LOCAL nH := 60, nTime := 1000 //, lClose := .F. LOCAL hWnd, aHmg, lBlk := HB_ISBLOCK(bBlk) LOCAL y := 0, x := 0, w := 320, h := nH PRIV lClose := .F. DEFAULT bBlk := {|| Nil }, ; nStep := 10, ; nMax := 250, ; cCapt := gTxt(Wait) hWnd := iif( _HMG_BeginWindowMDIActive, GetActiveMdiHandle(), GetActiveWindow() ) aHmg := Save_Rest_HMG(hWnd) DEFINE WINDOW wWait ; AT y, x ; WIDTH w + nX * 2 ; HEIGHT h + nY * 2 + GetTitleHeight() ; TITLE cCapt ; MODAL NOSIZE NOSYSMENU ; ON INIT ( SetWaitCursor( App.Handle ), ; SetWaitCursor( This.ProgressBar.Handle ), ; CursorWait(), oWin:PostMsg(1), ; This.tWait.Enabled := .T., DoEvents(), ; Eval(bBlk, oWin), ; oWin:PostMsg(2), DoEvents() ) ; ON RELEASE ( This.tWait.Enabled := .F., ; This.ProgressBar.Value := oWin:Cargo[3], ; InkeyGui(500), ; SetArrowCursor( This.ProgressBar.Handle ), ; SetArrowCursor( App.Handle ), ; CursorArrow(), InkeyGui(100), ; Save_Rest_HMG(aHmg) ) ; ON INTERACTIVECLOSE lClose PRIV oWin := ThisWindow.Object oWin:Cargo := { nStep, 0, nMax } oWin:Event( 1, {|ow,nk| nk := ow:Cargo[2] + ow:Cargo[1], ; ow:Cargo[2] := iif( nk > ow:Cargo[3], 0, nk ), ; wWait.ProgressBar.Value := ow:Cargo[2], ; iif( ow:Cargo[2] == 0, ow:PostMsg(1), ), ; wWait.tWait.Enabled := .T., DoEvents() } ) oWin:Event( 2, {|| lClose := .T., wWait.Release } ) oWin:Event( 3, {|| wWait.tWait.Enabled := .F., DoEvents() } ) oWin:Event( 4, {|| wWait.tWait.Enabled := .T., DoEvents() } ) @ y, x PROGRESSBAR ProgressBar RANGE 0, nMax ; WIDTH ThisWindow.ClientWidth ; HEIGHT ThisWindow.ClientHeight DEFINE TIMER tWait INTERVAL nTime ACTION ( wWait.tWait.Enabled := .F., oWin:PostMsg(1) ) This.tWait.Enabled := .F. y := App.Row + int((App.Height - h) / 2) x := App.Col + int((App.Width - w) / 2) h += nY MoveWindow( oWin:Handle, x, y, w, h ) END WINDOW ACTIVATE WINDOW wWait Save_Rest_HMG(aHmg) RETURN NIL
|
|
|
|
|
| |
Пост N: 682
Зарегистрирован: 08.07.06
|
|
Отправлено: 12.11.22 14:00. Заголовок: Dima пишет: Покажи ..
Dima пишет: Вот так работает у меня hb_ZipFile(): Тут два прогресса: общий, по всем файлам плюс внутри каждого файла. А вот при копировании архива на съемный носитель получается сразу 100% и потом FCLOSE(). Пойду почитаю про hb_vfFWrite(). Потому как шаманства со счетчиком не очень идея, тк сложно угадать реальное время записи - на флэшке одна скорость, на удаленном бэкап сервере под своей нативной ОС (там что-то типа TrueNAS OS) - своя скорость. При копировании даже внутри локальной сети - третья скорость... Плюс целый зоопарк машин с разной производительностью, плюс разная загрузка сети в зависимости от числа активных юзеров...
|
|
|
|
| |
Пост N: 683
Зарегистрирован: 08.07.06
|
|
Отправлено: 12.11.22 14:06. Заголовок: Pasha пишет: Наблюд..
Pasha пишет: цитата: | Наблюдал подобное при копировании файлов фаром на флешку. У него свой прогресс-бар. Может быть такой эффект дает антивирус |
| Вот как раз Far копирует так, как нужно, прогресс движется достаточно равномерно и при достижении 100% копирование полностью завершено: если тут-же нажать на иконку "безопасного извлечения" - все ок.
|
|
|
|
| постоянный участник
|
Пост N: 4179
Зарегистрирован: 17.02.12
|
|
Отправлено: 12.11.22 15:29. Заголовок: Sergy пишет Пойду по..
Sergy пишет цитата: | Пойду почитаю про hb_vfFWrite() |
| Если поможет, хорошо, и если в ней есть упр. буф. windows цитата: | Потому как шаманства со счетчиком не очень идея, тк сложно угадать реальное время записи |
| Если сохранить (при первом копировании или при каждом) для файла[ов] время записи (для устройства от fOpen() до fClose()) в ini (раб. месте) для конкретной PC, то потом можно ставить (с коэффициентом) это время, например в схему выше по таймеру и уже, думаю, будешь попадать в "струю" как надо. PS hbedit редактор имеет файл открытий файлов с запоминанием CDP и ..., ставлю у себя в ini 1500 строк для этого журнала работает как часы PS2 Переписав на устройство, например, тестовый файл (в скрытом режиме) и удалив его потом, можно опр условную единицу для расчета счетчика и шага и исп. это значение исходя из длины файлов + коэффициент увеличения, сохранить это значение и исп. его для работы с этим устройством. Тоже вариант "бегунка" по таймеру
|
|
|
|
| |
Пост N: 684
Зарегистрирован: 08.07.06
|
|
Отправлено: 12.11.22 16:49. Заголовок: Итак Связка hb_vfOp..
Итак Связка hb_vfOpen() -> hb_vfWrite() -> hb_vfClose() ЗАРАБОТАЛА в нужном ключе. Потому что есть волшебный hb_vfCommit() Единственное, что пришлось повозиться с hb_vfOpen(), тк при использовании его вместо FCREATE() нужно указывать атрибуты FO_CREAT+FO_TRUNC+FO_WRITE. Я сначала поставил только первый, получил os error - 5 - Access denied и созданный выходной файл нулевого размера. Часа полтора прыгал, не мог понять, где косяк - как так - файл создать можно, а записать в него нельзя. И нужно поиграть размером буфера. Был у меня по умолчанию 16Кб, он сильно замедляет процесс. Поставил размером 5% от MEMORY( HB_MEM_BLOCK ) - получился 100 мегабайт буфер, прогресс на медленных носителях выходит "рывками". Остановился на подходящем - 512Kb. С ним все норм. Спасибо за помощь, друзья. PS: вирусы шифровальщики - зло. Делайте бэкапы регулярно пожалуйста.
|
|
|
|
| Администратор
|
Пост N: 4095
Зарегистрирован: 23.05.05
|
|
Отправлено: 13.11.22 10:29. Заголовок: Sergy пишет: Потому..
Sergy пишет: цитата: | Потому что есть волшебный hb_vfCommit() |
| Оказывается, есть и hb_FCommit, который можно использовать с FOpen/FWrite
|
|
|
|
|
| |
Пост N: 685
Зарегистрирован: 08.07.06
|
|
Отправлено: 13.11.22 12:35. Заголовок: Pasha пишет: Оказыв..
Pasha пишет: цитата: | Оказывается, есть и hb_FCommit, который можно использовать с FOpen/FWrite |
| Ваще крутяк Посмотрел, как он реализован: HB_FUNC( HB_FCOMMIT ) { HB_ERRCODE uiError = 6; if( HB_ISNUM( 1 ) ) { hb_fsCommit( hb_numToHandle( hb_parnint( 1 ) ) ); uiError = hb_fsError(); } hb_fsSetFError( uiError ); }
|
|
|
|