30. juli 2001 - 08:59Der er
5 kommentarer og 1 løsning
Alle filnavne og størrelser via API kald.
Findes der et API kald der returnerer en eller anden datastruktur med navne og størrelser på samtlige filer på harddisken.
Jeg bruger idag en rekursiv søgning (findfirstfile & findnextfile), men jeg nægter at tro at det er den hurtigste metode. Er der nogen der ved noget ? Jeg har set andre programmer der på få sekunder henter 10000 filnavne. Hvordan h.... gør de det.
dr.truti>> Ville det ikke være spildt arbejde hvis han smed koden ud? Og hvordan skulle han gøre det sådan rent fysisk? - Bare ud af vinduet med toweret? :-)
Private Type FILETIME dwLowDateTime As Long dwHighDateTime As Long End Type Private Type WIN32_FIND_DATA dwFileAttributes As Long ftCreationTime As FILETIME ftLastAccessTime As FILETIME ftLastWriteTime As FILETIME nFileSizeHigh As Long nFileSizeLow As Long dwReserved0 As Long dwReserved1 As Long cFileName As String * MAX_PATH cAlternate As String * 14 End Type
Private Declare Function FindFirstFile Lib \"kernel32\" Alias \"FindFirstFileA\" (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long Private Declare Function FindNextFile Lib \"kernel32\" Alias \"FindNextFileA\" (ByVal hFindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Long Private Declare Function FindClose Lib \"kernel32\" (ByVal hFindFile As Long) As Long
Sub Main() SearchDir \"C:\" End Sub
Sub SearchDir(strDir As String) Dim hFind As Long, strFilename As String Dim lpFindData As WIN32_FIND_DATA hFind = FindFirstFile(strDir & \"\\\" & \"*.*\", lpFindData) If hFind Then strFilename = Left(lpFindData.cFileName, InStr(1, lpFindData.cFileName, Chr(0)) - 1) If Not strFilename = \".\" And Not strFilename = \"..\" Then Debug.Print strDir & \"\\\" & strFilename & \" (\" & lpFindData.nFileSizeLow & \" bytes)\" If lpFindData.dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY Then Call SearchDir(strDir & \"\\\" & strFilename) End If End If While FindNextFile(hFind, lpFindData) strFilename = Left(lpFindData.cFileName, InStr(1, lpFindData.cFileName, Chr(0)) - 1) If Not strFilename = \".\" And Not strFilename = \"..\" Then Debug.Print strDir & \"\\\" & strFilename & \" (\" & lpFindData.nFileSizeLow & \" bytes)\" If lpFindData.dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY Then Call SearchDir(strDir & \"\\\" & strFilename) End If End If DoEvents Wend Call FindClose(hFind) End If End Sub
Du kan jo bare skifte Debug.Print ud med noget andet!
Det mindede meget om det jeg havde selv, men i mellemtiden har jeg fundet ud af at hvis jeg istedet bruger VB funktionen \"filelen\" kombineret med ovenstående kører det langt hurtigere, end hvis jeg hentede filstørrelsen via API kaldet, som jeg gjorde tidligere. Underligt, men \"if it works, don\'t fix it\"
Huh?! Det virker da mærkeligt at FileLen skulle bruge mindre computer kræft en at hente nFileSizeLow fra WIN32_FIND_DATA. Dette burde i teorien blot tage 1 clockcyclus plus RAM delay plus tiden for at konvertere det til tekst. FileLen skal først til at finde filen i filsystemet og så læse størrelsen. Og så oven i det tiden for at konvertere det til tekst. Men selvfølgelig hvis du før bruge API-funktionen CreateFile, GetFileSize og CloseHandle, så ville det tage langt længere tid, men hvorfor gøre det, når WIN32_FIND_DATA indeholder alle informationerne?!
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.