Мда fluke... а ведь я тебя предупреждала: не суйся - снова мордой об лавку стукнут!! Но Steel Brand не просто стукнул, а ваще растоптал.. всю морду в кровь разбил...
Но ко всему надо относиться философски: на будущее умнее будешь
Private Structure FILETIME
Public dwLowDateTime As Integer
Public dwHighDateTime As Integer
End Structure
Private Structure WIN32_FIND_DATA
Public Attributes As Integer
Public CreationTime As FILETIME
Public LastAccessTime As FILETIME
Public LastWriteTime As FILETIME
Public SizeHigh As Integer
Public SizeLow As Integer
Public Reserved0 As Integer
Public Reserved1 As Integer
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> Public Name As String
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=14)> Public Alternate As String
End Structure
Private Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileA" (ByVal lpFileName As String, ByRef lpFindFileData As WIN32_FIND_DATA) As Integer
Private Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileA" (ByVal hFindFile As Integer, ByRef lpFindFileData As WIN32_FIND_DATA) As Integer
Private Declare Function GetFileAttributes Lib "kernel32" Alias "GetFileAttributesA" (ByVal lpFileName As String) As Integer
Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Integer) As Long
Private Const MAX_PATH As Short = 260
Private Const MAXDWORD As Short = &HFFFFS
Private Const INVALID_HANDLE_VALUE As Short = -1
Private Const FILE_ATTRIBUTE_ARCHIVE As Short = &H20S
Private Const FILE_ATTRIBUTE_DIRECTORY As Short = &H10S
Private Const FILE_ATTRIBUTE_HIDDEN As Short = &H2S
Private Const FILE_ATTRIBUTE_NORMAL As Short = &H80S
Private Const FILE_ATTRIBUTE_READONLY As Short = &H1S
Private Const FILE_ATTRIBUTE_SYSTEM As Short = &H4S
Private Const FILE_ATTRIBUTE_TEMPORARY As Short = &H100S
Public Files As New Collections.Generic.List(Of String)
Public ErrFiles As New Collections.Generic.List(Of String)
Public Sub Read(ByVal Path As String)
SearchForFiles(Path)
End Sub
Private Sub SearchForFiles(ByVal Folder As String)
'cFiles.Capacity = cFiles.Capacity + 500
 im hFnd As Integer
 im WFD As New WIN32_FIND_DATA
 im Name As String
If VB.Right(Folder, 1) <> "\" Then Folder = Folder & "\"
hFnd = FindFirstFile(Folder & "*.*", WFD)
If hFnd = -1 Then
ErrFiles.Add(Folder)
Exit Sub
Else
 o While FindNextFile(hFnd, WFD) > 0
If (InStr(WFD.Name, Chr(0)) > 0) Then
Name = VB.Left(WFD.Name, InStr(WFD.Name, Chr(0)) - 1)
Else
Name = WFD.Name
End If
If Not (Name = "." Or Name = ".." Then
If (WFD.Attributes And 16) > 0 Then
SearchForFiles(Folder & Name)
Else
Files.Add(Folder & Name)
End If
End If
и еще, от запуска к запуску, количество файлов на системном диске меняется, а если учитывать что ты еще и в инете сидишь то и подавно! если мой код не получил доступ к системным файлам hiberfil.sys или например из папки Recycled, то в этом нет ничего страшного, по поводу имен, да стандартов надо придерживаться, но имхо это сугубо личное дело. тем более что этот пример перенесен из статьи по VB6.0
а госпожу "Нику", попрошу воздержаться от комментариев, когда разговор ведут мужчины. дабы вчера я от нее не слышал комментариев, случайно не по тому, что появилась теоретическая возможность опровергнуть ее слова?
я не говорю, что данный пример правильно спроектирован. искать недоработки это дело рук Steel Brand. он только демонстрирует преимущество api. Если Steel Brand, c его феноменальными возможностями оттачивать напильником "чужой код", доделает его, то добьется еще большего результата
Так лучше, твой код находит сравнимое количество файлов
Steel Brand:
00:00:08.4700000
Найдено файлов: 310799
fluke:
00:00:04.6080000
Найдено файлов: 310104
Почему-то количество файлов все равно отличается причем не на 1-2 файла а намного больше (675 файлов) - причем это не зависит от того что файлы добавляются или удаляются между вызовами, так как эта разница постоянно сохраняется, т.е где-то ты все-таки налажал и это нужно исправить.
Разница в скорости (если опустить разницу в результатах) - почти в два меньшее время.
Пояснить это очень просто.
Directory.GetDirectories и Directory.GetFiles фактически выполняют два цикла перебора содержимого дирректории - один раз для файлов, один раз для папок.
В твоем коде в одном цикле выполняется перебор как папок так и файлов.
Т.е. речь в разнице скорости идет не о том что Win32API быстрее чем FCL (хотя в теории с этим поспорить нельзя) - а о том что в данном случае FCL ввиду особенностей реализации работает медленнее чем относительно оптимальный алгоритм на Win32API (я думаю можно даже говорить не об относительной а о обычной оптимальности так как автор статьи из которой ты содрал пример наверняка об этом позаботился).
Ликвидировать эту разницу можно, воспользовавшись другой функцией FCL - Directory.InternalGetFileDirectoryNames, которая отработает ровно столько же времени сколько и твой вариант с API, хотя архитектурно это не правильно. Это как раз тот случай когда ради более верного дизайна приходится жертвовать скорость.
Почему в FCL нет обычной функции для получения списка как файлов так и папок? Я думаю это очень просто объяснить - такой сценарий является достаточно редким поэтому его реализацию не делали, хотя она, как ты сам можешь убедиться, есть в виде внутренней функции.
содрал, говоришь? я не содрал, а переписал код под с VB6 под VB.NET, ты же даже декомпелировать не смог корректно, и сразу трубить, мол, все это фигня, вместо того, что бы исправить, то, что декомпелировал! ну мож просто сил и знаний не хватило. то, что есть разница в количестве, объясняю: во-первых, если в имени файла присутствуют непечатные символы, функция не возвращает хендл файла, или нет доступа к этой папке. почему так? все вопросы к мелкомягким. но если даже тебе и надо получить эти файлы, то в месте где не получен хендл файла, стандартную обработку. но результат всеравно буит быстрее.
что и требовалось доказать. а то что ты пишешь, это все-го лишь оправдания! ведь как ты говорил раньше, имхо быстродействие критично всегда, а теперь говоришь что уже можно и пожертвовать, как так?
же даже декомпелировать не смог корректно, и сразу трубить, мол, все это фигня, вместо того, что бы исправить, то, что декомпелировал!
Декомпилировал
Я не намерен исправлять баги чужого кода даже если он получен из декомплилятора.
что есть разница в количестве, объясняю: во-первых, если в имени файла присутствуют непечатные символы, функция не возвращает хендл файла, или нет доступа к этой папке. почему так?
Я не знаю почему так, но функции GetFiles и GetDirectories, которые используют теже FindFirstFile и FindNextFile (если посмотреть декомпилятором) отлично работают правильно в вотличие от твоего кода.
что и требовалось доказать. а то что ты пишешь, это все-го лишь оправдания! ведь как ты говорил раньше, имхо быстродействие критично всегда, а теперь говоришь что уже можно и пожертвовать, как так?
Тебе же уже объяснили с чем это связано - просто из-за специфики конкретной задачи тебе можно выполнить один цикл вместо двух.
Если банально изменим условия - вместо списка файлов получать только список дирректорий, время будет идентичным, если даже не проигрышным для АПИ.
"но функции GetFiles и GetDirectories, которые используют теже FindFirstFile и FindNextFile (если посмотреть декомпилятором)", и ты говоришь базовые функции будут работать медленее потомков? Бред))))))
лано что с тобой спорить, я могу признать, что с с массивом протупил. ты же не можешь поверить в то что апи в даном случаи быстрее и пытаешься что-то придумать. (при том, сам говоришь GetFiles и GetDirectories используют эти функции)
ты же не можешь поверить в то что апи в даном случаи быстрее и пытаешься что-то придумать. (при том, сам говоришь GetFiles и GetDirectories используют эти функции)
и ты говоришь базовые функции будут работать медленее потомков?
Мне не нужно верить ничему кроме своих глаз.
Что я пытаюсь объяснить тебе - так это то что внутри GetDirectories и GetFiles идет вызов тех же АПИ-функций которые идут и в твоем коде и алгоритмы работы функций сравнительно одинаковы (за исключением того что в FCL код более рассчитан на универсальность и защиту от ошибок).
И разницы в скорости работы нет кроме накладных расходов на собственно вызов функции которые, сравнительно со скоростью работы диска, практически равны нулю.
при том, сам говоришь GetFiles и GetDirectories используют эти функции
Ты жжошь, а как по твоему еще эти функции должны работать? Прямой доступ к устройству что ли?
Продолжайте в том же духе и скоро мы будем лицезреть надписи типа: "А вот сначала надо использовать функцию 4ЕН прерывания 21Н, а тока потом 4FH..." или "А вот у меня на 4 наносекунды быстрее выполняется..."
Подаешь на пин 34 ток 0.85 миллиампер вместо 0.84, как по стандарту, и получаешь преимущество на целых 40 фемтосекунд! Это масса большего количества электронов гравитацией заставляет диск винчестера крутиться быстрее.