Автор вопроса: Smith | Web-сайт:Не хочу ломать голову, если её уже сломал кто-то другой. | ICQ: ненавижу
Прога получает командной строкой ListBox куда нужно отвечать, начальный путь поиска и ещё один пустой параметр обозначающий, что поиск нужно вести с DoEvent'ами.
Экзешник после упэикса получается 4,5кБ.
Option Explicit
Private Declare Function SetPriorityClass Lib "kernel32" (ByVal hProcess As Long, ByVal dwPriorityClass As Long) As Long
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long
Private FSO As New FileSystemObject
Private Slow As Boolean
Private hWnd As Long
Private Sub Main()
Dim StartLn As Long
Dim Start() As String
Start = Split(Command, "/")
StartLn = UBound(Start)
If StartLn > 0 Then
If IsNumeric(Start(0)) Then
ChDir "\"
Call SetPriorityClass(GetCurrentProcess, 256)
hWnd = CLng(Start(0))
Slow = StartLn = 2
FindEmpty Start(1)
SendMessage hWnd, 384, 0, "/" 'это сигнал об окончании работы
End If
End If
End
End Sub
Private Sub FindEmpty(ByRef Path As String)
Dim Size As Single
Dim Fold As Object
Dim Item As Object
On Error Resume Next
Set Fold = FSO.GetFolder(Path)
Size = Fold.Size
If Err.Number > 0 Then Size = 1
If Size > 0 Then
If Slow Then DoEvents
For Each Item In Fold.SubFolders
FindEmpty (Path & "\" & Item.Name)
Next
Else
SendMessage hWnd, 384, 0, Path
End If
End Sub
Господа, есть соображения, что можно сделать, чтоб улучшить характеристики?
Даже в таком виде меньше не становится, без приоритета может стать медленнее
Option Explicit
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long
Private FSO As New FileSystemObject
Private Slow As Boolean
Private hWnd As Long
Private Sub FindEmpty(ByRef Path As String)
Dim Size As Single
Dim Fold As Object
Dim Item As Object
On Error Resume Next
Set Fold = FSO.GetFolder(Path)
Size = Fold.Size
If Err.Number > 0 Then Size = 1
If Size > 0 Then
If Slow Then DoEvents
For Each Item In Fold.SubFolders
FindEmpty (Path & "\" & Item.Name)
Next
Else
SendMessage hWnd, 384, 0, Path
End If
End Sub
Steel Brand это на VB6, тебе интересно?
Прога получает командной строкой ListBox куда нужно отвечать, начальный путь поиска и ещё один пустой параметр обозначающий, что поиск нужно вести с DoEvent'ами.
Экзешник после упэикса получается 4,5кБ.
Его я сую в ресурс основной проги, прога ищет пустые папки.
Ну зачем же пинать.. чтож ты о нас такого плохого мнения? Почему такое предвзятое отношение?
Ты мне лучше вот что скажи.. Для чего все эти танцы с бубнами? Почему ты не включил этот модуль в основную программу а добавил в ресурсы?
Затем ты ее извлекаешь из ресурсов, сохраняешь на винт, запускаешь процесс с параметрами, даешь ему максимальный приоритет и уже тот заполняет список в основной проге через сообщения. К чему все это???
Если только это не попытка эмуляции "многопоточности" чтоб основная софтина не висела во время сканирования папок.. Сдается мне, что она подвисает изрядно если ей задать корень диска в качестве рута.. и если это так, то повышенный приоритет в данном случае это не более, чем костыль..
И тормоза твои тут скорее всего не из за приоритета, а из-за FSO (имхо).. более того, ты на каждой итерации цикла получаешь размер папки со всем содержимым, что собственно тоже будет изрядно тормозить.. Вот представь, у тебя есть папка.. а ней 5 уровней вложенности.. на первом шаге ты получишь размер всех уровней, на втором размер 4 уровней и т.д.. и в результате ты 5 раз получишь размер одной и той же папки(последней).. и это при условии, что там вложено по 1 папке! А если там, скажем, по 10 папок, что тогда? То то же... смысл в том, что чем больше уровней вложенности, тем больше раз ты будешь получать размер одних и тех же папок и файлов.. а получение размера - это тоже время и,соответственно, тоже рекурсия! Вот,собственно, и все твои тормоза.
Это была критика.. теперь предложение..
Сразу оговорюсь: все, что будет сказано ниже - мое имхо.
Тебе следует отказаться от FSO, и реализовать все на API (Примеров перебора файлов в сети на апи - туча!) При этом не получать размер папки, а просто узнать,есть ли в ней хоть 1 файл или папка или нет.. если есть, то дальше сканить смысла нету(значит она не пустая) и переходить на следующий уровень вложенности.
Разумеется, это увеличит немного размер проги, но выигрыш в скорости будет чудовищный.. и не надо будет никаких завышенных приоритетов и отдельных процессов.
Таки нет тут ничего забавного, это редкое проявление моей тактичности )
Откуда мне знать в каком вы часовом поясе ) Может Вам на работу пора или ещё чего, ну правда
EROS, Ваш пост для меня цены не имеет!
Все танцы это именно то, о чем вы пишете.
Для меня такое решение гораздо проще и понятнее костылей многопоточности VB6 ) пусть я и неправ, но я ещё совсем молод )
А костыль реального времени как ни странно дал хоть и не чудовищный, но весьма значительный прирос скорости.
Изгаляться с апи SendMessage пришлось потому, что умные ребята распространяют массово компиляции ХР с выключеной по умолчанию службой DDE, на которую я наивно полагался по началу.
FSO хоть и сделана Микрософтом, но не такая уж дремучая модель как вы думаете, я просто не уверен,
что смогу написать что-то лучше используя апи, хотя и предпочитаю апи многим современным средствам.
Это в смысле безценный, или же наоборот бестолковый? )))
Для меня такое решение гораздо проще и понятнее костылей многопоточности VB6
так никто и не призывает тебя юзать многопоточность в VB6 (это реально геморрой)! Напротив, я призываю тебя изменить реализацию алгоритма, что избавит тебя от всяких костылей, в том числе и от ресурсов с SendMessage.
Не уверен, что стоит переходить от получения размера папки к определению её содержимого.
FSO подсчитывая размер папки наверняка использует апи, я не смогу написать это лучше микрософтовцев.
Ну даже если и есть в папке файл размером 0 байт, то наверняка ценность этого файла равна размеру )