[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

microsoft.public.vb.general.discussion

FindFileFirst vs Dir() vs Windows Properties

BeeJ

8/28/2011 7:04:00 PM

I have been playing with this for hours (seriuosly) and cannot figure
out what I am doing wrong.

I have been using Dir()/Dir and FindFirstFile/FindNextFile to get a
list of files.
I compared results with each other and also with Window Properties.
Windows Properties always gives me more filename (count) and Dir and
FindFirst also mismatch.

I am using Randy's code for FindFirstFile/FindNextFile
http://vbnet.mvps.org/index.html?code/fileapi/folderc...
and get a different answer than Windows Properties.
I have tried all the filters I can think of.
*; *.*; *.

I tried changing the initial
hFile = FindFirstFile(sRoot & "*.*", WFD)
to
hFile = FindFirstFile(sRoot & "*", WFD)
without success

thinking that a file without an ext would not match *.*
what about files with no name e.g. .txt
you can create using Name "Temp.txt" as ".txt"

I tried changing API for match to simple Like
MatchSpecAPI = (PathMatchSpec(StrPtr(sFile), StrPtr(sSpec)) =
fp.bFindOrExclude)
to Like
If sFile Like m_asFilter(lX) Then ' loops on multiple filters
and go the same answer

In one case using Dir()/Dir it would not find files without an
extension.
Just so you know I am looking at the acual results.

Now I am scanning a folder with ~32k files and getting a mismatch of
31,837 (Randy's) vs 31,849 (Windows Properties)
There are 4,926 folders (Windows Properties) in this tree.

So I am wondering what Windows Properties is calling a file that I
cannot see using Randy's code.
Is there some filetype that FindFirstFile/FindNextFile cannot find?
I need to find all file types.

OK, if no one can tell me off the top of their head, then I am not sure
what to do next.

I have tried to pair down the subfolders to see if I can detect a
mismatch but to no avail.

Suggestions please.


23 Answers

Mike Williams

8/28/2011 8:20:00 PM

0

"BeeJ" <nospam@spamnot.com> wrote in message
news:j3e3fp$9ir$1@dont-email.me...

> I have been playing with this for hours (seriuosly) and cannot
> figure out what I am doing wrong.

Welcome to the club ;-)

> I have been using Dir()/Dir ans FindFirstFile/FindNextFile to
> get a list of files. I compared results with each other and also
> with Window Properties. Windows Properties always gives
> me more filename (count) and Dir and FindFirst also mismatch.
> I am using Randy's code for FindFirstFile/FindNextFile
> http://vbnet.mvps.org/index.html?code/fileapi/folderc...
> and get a different answer than Windows Properties.

Well I don't know what Randy's code is doing but the following code should
(hopefully?) return the correct result for you. It returns the total number
of files and folders and the total byte size of the files and the total
amount of disk space they use and it correctly deals with files over both
the 2GB and the 4GB size boundary. Does this code return the results you are
expecting? (Paste it into a VB Form containing one Command Button).

Mike

Option Explicit
Private Declare Function GetDiskFreeSpace _
Lib "kernel32" Alias "GetDiskFreeSpaceA" _
(ByVal lpRootPathName As String, _
lpSectorsPerCluster As Long, _
lpBytesPerSector As Long, _
lpNumberOfFreeClusters As Long, _
lpTotalNumberOfClusters As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" _
Alias "RtlMoveMemory" (ByRef Destination As Any, _
Source As Any, ByVal Length As Long)
Private Declare Function SHBrowseForFolder _
Lib "shell32.dll" (bBrowse As BrowseInfo) As Long
Private Declare Function SHGetPathFromIDList _
Lib "shell32.dll" (ByVal lItem As Long, _
ByVal sDir As String) As Long
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
Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
Private Const MAX_PATH = 260
Private Type WIN32_FIND_DATA
lngFileAttributes As Long
ftCreationTime As FILETIME
ftLastAccessTime As FILETIME
ftLastWriteTime As FILETIME
lngFileSizeHigh As Long
lngFileSizeLow As Long
lngReserved0 As Long
lngReserved1 As Long
fileName As String * MAX_PATH
strAlternate As String * 14
End Type
Private Type BrowseInfo
hWndOwner As Long
pidlRoot As Long
sDisplayName As String
sTitle As String
ulFlags As Long
lpfn As Long
lParam As Long
iImage As Long
End Type
Private Const FILE_ATTRIBUTE_ARCHIVE = &H20
Private Const FILE_ATTRIBUTE_COMPRESSED = &H800
Private Const FILE_ATTRIBUTE_DIRECTORY = &H10
Private Const FILE_ATTRIBUTE_HIDDEN = &H2
Private Const FILE_ATTRIBUTE_NORMAL = &H80
Private Const FILE_ATTRIBUTE_READONLY = &H1
Private Const FILE_ATTRIBUTE_SYSTEM = &H4
Private Const FILE_ATTRIBUTE_TEMPORARY = &H100
Private Const BIF_RETURNONLYFSDIRS As Long = &H1
Private directories As Long
Private folders As Long
Private files As Long
Private totalSize As Currency
Private totalSizeOnDisk As Currency
Private loMask As Long
Private hiMask As Long
Private clusterSize As Currency

Public Sub GetClusterSize(disk As String)
' Note: GetDiskFreeSpace API function cannot report
' sizes of disks greater than 2GB (you must instead
' use the newer GetDiskFreeSpaceEx). However, here
' we are using it only to get the cluster size, so
' it is okay.
Dim s1 As String, sectorsPerCluster As Long
Dim bytesPerSector As Long, free As Long
Dim total As Long, retVal As Long
Dim bytesperCluster As Long
retVal = GetDiskFreeSpace _
(disk, sectorsPerCluster, bytesPerSector, free, total)
bytesperCluster = sectorsPerCluster * bytesPerSector
loMask = bytesperCluster - 1
hiMask = &HFFFFFFFF - loMask
clusterSize = CCur(bytesperCluster / 10000&)
End Sub

Private Function Browse_Folder() As String
Dim bInf As BrowseInfo
Dim lItem As Long
Dim sDirName As String
Dim hwnd As Long
bInf.hWndOwner = Me.hwnd
bInf.sDisplayName = Space$(MAX_PATH)
bInf.sTitle = "Select Folder"
bInf.ulFlags = BIF_RETURNONLYFSDIRS
lItem = SHBrowseForFolder(bInf)
If lItem Then
sDirName = Space$(MAX_PATH)
If SHGetPathFromIDList(lItem, sDirName) Then
Browse_Folder = Left(sDirName, InStr(sDirName, _
Chr$(0)) - 1)
Else
Browse_Folder = ""
End If
End If
End Function

Private Sub countFiles(folderPath As String, _
recurse As Boolean)
Dim fd As WIN32_FIND_DATA
Dim hFind As Long
Dim strFile As String
Dim strSearch As String
Dim fileSize As Currency
Dim SizeOnDisk As Currency
Dim roundUp As Boolean
If Right$(folderPath, 1) <> "\" Then
folderPath = folderPath & "\"
End If
strSearch = folderPath & "*"
hFind = FindFirstFile(strSearch, fd)
If hFind > 0 Then
Do
If (fd.lngFileAttributes And FILE_ATTRIBUTE_DIRECTORY) _
= FILE_ATTRIBUTE_DIRECTORY Then
If Left$(fd.fileName, 1) = "." Then
' ignore these
Else
' It is a directory
folders = folders + 1
If recurse Then
countFiles folderPath & Left$(fd.fileName, _
InStr(fd.fileName, Chr(0)) - 1), recurse
End If
End If
Else
files = files + 1
If (fd.lngFileSizeLow And loMask) <> 0 Then
roundUp = True
Else
roundUp = False
End If
fd.lngReserved0 = fd.lngFileSizeHigh
CopyMemory fileSize, fd.lngFileSizeLow, 8
'
totalSize = totalSize + fileSize
If roundUp Then
fd.lngFileSizeLow = fd.lngFileSizeLow _
And hiMask
End If
CopyMemory SizeOnDisk, fd.lngFileSizeLow, 8
'
If roundUp Then '
totalSizeOnDisk = totalSizeOnDisk + _
SizeOnDisk + clusterSize
Else
totalSizeOnDisk = totalSizeOnDisk + _
SizeOnDisk
End If
End If
Loop While CBool(FindNextFile(hFind, fd))
Call FindClose(hFind)
End If
End Sub

Private Sub Command1_Click()
Dim sfolder As String, s1 As String
Dim t1 As Single, t2 As Single
Dim Sectors As Long, Bytes As Long
Dim FreeC As Long, TotalC As Long
Dim total As Long, Freeb As Long
Command1.Enabled = False
sfolder = Browse_Folder
Me.Refresh: DoEvents
If sfolder = "" Then
Caption = "No Folder Selected"
Else
GetClusterSize Left$(sfolder, InStr(sfolder, "\"))
directories = 0
folders = 0
files = 0
totalSize = 0
totalSizeOnDisk = 0
s1 = Caption: Caption = "Please wait . . ."
t1 = Timer
countFiles sfolder, True
t2 = Timer
Caption = s1
s1 = Format(files, "###,###,##0") & " files, "
s1 = s1 & Format(folders, "###,###,##0") & " folders."
s1 = s1 & vbCrLf & _
"Total file size = " & _
Format((totalSize * 10000&), "###,###,###,##0")
s1 = s1 & vbCrLf & _
"Total size on disk = " & _
Format((totalSizeOnDisk * 10000&), "###,###,###,##0")
s1 = s1 & vbCrLf & _
"Time taken = " & Format(t2 - t1, "###.00") & " seconds."
MsgBox s1
End If
DoEvents
Command1.Enabled = True
End Sub



(nobody)

8/28/2011 8:28:00 PM

0

"BeeJ" <nospam@spamnot.com> wrote in message
news:j3e3fp$9ir$1@dont-email.me...
>I have been playing with this for hours (seriuosly) and cannot figure out
>what I am doing wrong.
>
> I have been using Dir()/Dir and FindFirstFile/FindNextFile to get a list
> of files.
> I compared results with each other and also with Window Properties.
> Windows Properties always gives me more filename (count) and Dir and
> FindFirst also mismatch.

My guess is that it's a hidden file/folder search mismatch.


(nobody)

8/28/2011 8:40:00 PM

0

Another possibility is that some folders may contain Unicode characters that
can't be represented by the current code page, and so you have a "wrong"
folder name after the ANSI to Unicode translation, and the OS tells you it
doesn't exist. Try your search on the C:\Windows folder because it's most
likely all English. You would need the W version of the search functions,
and change the String parameters in the API declaration to:

ByVal SomeStringVar As Long

And call it in these ways:

ByVal StrPtr(SomeStringVar)
ByVal StrPtr("*")

"ByVal" above is actually redundant here, but if you forgot to use "ByVal"
in the parameter declaration, then it works both ways.

Don't forgot to change the "A" into "W" in the "Alias" in Declare statement.


BeeJ

8/29/2011 3:04:00 AM

0

On a test folder on my PC.

Windows Properties says
---------------------------
---------------------------
120,461 files, 21,547 folders.
Total file size = 9,514,572,335
Total size on disk = 7,595,208,352
Time taken = about one minute. (wasn't really interested .. yet)
---------------------------
NOTE: size on disk is smaller because compression is being used.


Your code is missing some files and folders like mine
---------------------------
Project1
---------------------------
120,411 files, 21,536 folders.
Total file size = 9,514,367,990
Total size on disk = 9,814,773,760
Time taken = 144.84 seconds.
---------------------------
OK
---------------------------

I added a FileSystemObject (FSO) recursive code to test against and
found that if was the same as the FindFirst EXCEPT that the FSO
recursive code did not include the files in the "root" folder
specified.
More to do.


Mike Williams

8/29/2011 9:50:00 AM

0

"BeeJ" <nospam@live.com> wrote in message
news:j3evk7$kgn$1@speranza.aioe.org...
> On a test folder on my PC.
> Windows Properties says
> 120,461 files, 21,547 folders.
> Total file size = 9,514,572,335
> Your code says
> 120,411 files, 21,536 folders.
> Total file size = 9,514,367,990
> Your code is missing some files and folders like mine . . .

.. . . or perhaps Windows Properties is reporting some files and folders that
should not have been legitimately counted, perhaps some data connected with
your disk compression stuff. At the moment you are jumping to a conclusion
that may or may not be correct. One of them is apparently wrong (or perhaps
even both of them). Maybe it is something to do with your compressed disk?
What happens if you write some VB6 code to randomly generate a large number
of deeply nested folders and populate them with a large number of files of
various different sizes? What do both methods report then? Do either of them
report the exact number of files and folders and the exact total file size
that you know your VB6 code created?

Mike




Mike Williams

8/29/2011 9:52:00 AM

0

"BeeJ" <nospam@live.com> wrote in message
news:j3evk7$kgn$1@speranza.aioe.org...

> Windows Properties says
> 120,461 files, 21,547 folders.
> Total file size = 9,514,572,335
> Total size on disk = 7,595,208,352
> Time taken = about one minute. (wasn't really interested .. yet)

With this kind of stuff the method you test first will almost always take
considerably longer than the method you test next.

Mike


Jason Keats

8/29/2011 10:45:00 AM

0

Nobody wrote:
> Another possibility is that some folders may contain Unicode characters that
> can't be represented by the current code page, and so you have a "wrong"
> folder name after the ANSI to Unicode translation, and the OS tells you it
> doesn't exist. Try your search on the C:\Windows folder because it's most
> likely all English. You would need the W version of the search functions,
> and change the String parameters in the API declaration to:
>
> ByVal SomeStringVar As Long
>
> And call it in these ways:
>
> ByVal StrPtr(SomeStringVar)
> ByVal StrPtr("*")
>
> "ByVal" above is actually redundant here, but if you forgot to use "ByVal"
> in the parameter declaration, then it works both ways.
>
> Don't forgot to change the "A" into "W" in the "Alias" in Declare statement.
>

I agree with Nobody's suggestions, but I've also been using the following:

Private Const MAX_PATH_Unicode As Long = 260 * 2 - 1

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(MAX_PATH_Unicode) As Byte
cAlternate(28) As Byte ' 28 for unicode, 14 for ANSI
End Type

ISTM that the Unicode version is slightly quicker.

As Mike Williams said, the first time will be considerably slower than
the next. For example, it took about 5.5 minutes for the initial run
against my C: drive, but 7 seconds for the next!

I guess that some sort of caching/search-indexing is going on.

I have an interest in this topic because I've been in the process of
converting a bunch of file functions from ANSI to Unicode. What a PITA
that is!

(nobody)

8/29/2011 12:24:00 PM

0

"Mike Williams" <Mike@WhiskyAndCoke.com> wrote in message
news:j3fnb1$o9l$1@dont-email.me...
> "BeeJ" <nospam@live.com> wrote in message
> news:j3evk7$kgn$1@speranza.aioe.org...
>> On a test folder on my PC.
>> Windows Properties says
>> 120,461 files, 21,547 folders.
>> Total file size = 9,514,572,335
>> Your code says
>> 120,411 files, 21,536 folders.
>> Total file size = 9,514,367,990
>> Your code is missing some files and folders like mine . . .
>
> . . . or perhaps Windows Properties is reporting some files and folders
> that should not have been legitimately counted, perhaps some data
> connected with your disk compression stuff. At the moment you are jumping
> to a conclusion that may or may not be correct. One of them is apparently
> wrong (or perhaps even both of them). Maybe it is something to do with
> your compressed disk? What happens if you write some VB6 code to randomly
> generate a large number of deeply nested folders and populate them with a
> large number of files of various different sizes? What do both methods
> report then? Do either of them report the exact number of files and
> folders and the exact total file size that you know your VB6 code created?

The OP makes it appear as if the routine always count files wrong, but it
only does this with some folders. I have duplicated the problem with one
folder that I have(Favorites folder) using your code. After converting it to
Unicode, I still get the same wrong numbers. It turns out the problem is in
this line:

If Left$(fd.fileName, 1) = "." Then

This was intended to eliminate the "." and ".." folders, but it also
eliminates file and folder names that start with ".". After making the
necessary changes, I got the same number of files as Windows Explorer, but
the folder count seems to have doubled, but it's probably a simple thing to
fix. Working with fixed size strings was a pain, so I had to turn it into
byte array in the UDT.



(nobody)

8/29/2011 12:49:00 PM

0

"Mike Williams" <Mike@WhiskyAndCoke.com> wrote in message
news:j3fnb1$o9l$1@dont-email.me...
> . . . or perhaps Windows Properties is reporting some files and folders
> that should not have been legitimately counted, perhaps some data
> connected with your disk compression stuff. At the moment you are jumping
> to a conclusion that may or may not be correct. One of them is apparently
> wrong (or perhaps even both of them). Maybe it is something to do with
> your compressed disk? What happens if you write some VB6 code to randomly
> generate a large number of deeply nested folders and populate them with a
> large number of files of various different sizes? What do both methods
> report then? Do either of them report the exact number of files and
> folders and the exact total file size that you know your VB6 code created?

Here is the Unicode version, which also supports paths with more than
MAX_PATH length. I already fixed the issue with the folder count, and it's
reporting exactly what Windows Explorer is reporting. Here are the minor
changes I made:

- FindFirstFile and WIN32_FIND_DATA declaration.
- Making sure that the path is prefixed with "\\?\". This is not necessary
if you know that the path will not exceed MAX_PATH, but it's good to use
nevertheless. This code is near the beginning of countFiles sub.
- Copying the file name from the byte array to a String variable and
removing the Null. This code is in the next line after the "Do" loop line.
- Removed the InStr in the call to countFiles sub since the Null is already
removed.

Here is the full code:

Option Explicit
Private Declare Function GetDiskFreeSpace Lib "kernel32" Alias _
"GetDiskFreeSpaceA" (ByVal lpRootPathName As String, _
lpSectorsPerCluster As Long, lpBytesPerSector As Long, _
lpNumberOfFreeClusters As Long, lpTotalNumberOfClusters As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
ByRef Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function SHBrowseForFolder Lib "shell32.dll" ( _
bBrowse As BrowseInfo) As Long
Private Declare Function SHGetPathFromIDList Lib "shell32.dll" ( _
ByVal lItem As Long, ByVal sDir As String) As Long
Private Declare Function FindFirstFile Lib "kernel32" Alias _
"FindFirstFileW" (ByVal lpFileName As Long, lpFindFileData As Any) _
As Long
Private Declare Function FindNextFile Lib "kernel32" Alias _
"FindNextFileW" (ByVal hFindFile As Long, _
lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindClose Lib "kernel32" ( _
ByVal hFindFile As Long) As Long
Private Declare Function lstrlenW Lib "kernel32" ( _
ByVal psString As Long) As Long
Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
Private Const MAX_PATH = 260
Private Type WIN32_FIND_DATA
lngFileAttributes As Long
ftCreationTime As FILETIME
ftLastAccessTime As FILETIME
ftLastWriteTime As FILETIME
lngFileSizeHigh As Long
lngFileSizeLow As Long
lngReserved0 As Long
lngReserved1 As Long
' fileName As String * MAX_PATH
' strAlternate As String * 14
fileName(0 To MAX_PATH * 2 - 1) As Byte
strAlternate(0 To 14 * 2 - 1) As Byte
End Type
Private Type BrowseInfo
hWndOwner As Long
pidlRoot As Long
sDisplayName As String
sTitle As String
ulFlags As Long
lpfn As Long
lParam As Long
iImage As Long
End Type
Private Const FILE_ATTRIBUTE_ARCHIVE = &H20
Private Const FILE_ATTRIBUTE_COMPRESSED = &H800
Private Const FILE_ATTRIBUTE_DIRECTORY = &H10
Private Const FILE_ATTRIBUTE_HIDDEN = &H2
Private Const FILE_ATTRIBUTE_NORMAL = &H80
Private Const FILE_ATTRIBUTE_READONLY = &H1
Private Const FILE_ATTRIBUTE_SYSTEM = &H4
Private Const FILE_ATTRIBUTE_TEMPORARY = &H100
Private Const BIF_RETURNONLYFSDIRS As Long = &H1
Private directories As Long
Private folders As Long
Private files As Long
Private totalSize As Currency
Private totalSizeOnDisk As Currency
Private loMask As Long
Private hiMask As Long
Private clusterSize As Currency
Private MaxSize As Long

Public Sub GetClusterSize(disk As String)
' Note: GetDiskFreeSpace API function cannot report
' sizes of disks greater than 2GB (you must instead
' use the newer GetDiskFreeSpaceEx). However, here
' we are using it only to get the cluster size, so
' it is okay.
Dim s1 As String, sectorsPerCluster As Long
Dim bytesPerSector As Long, free As Long
Dim total As Long, retVal As Long
Dim bytesperCluster As Long
retVal = GetDiskFreeSpace(disk, sectorsPerCluster, bytesPerSector, free, _
total)
bytesperCluster = sectorsPerCluster * bytesPerSector
loMask = bytesperCluster - 1
hiMask = &HFFFFFFFF - loMask
clusterSize = CCur(bytesperCluster / 10000&)
End Sub

Private Function Browse_Folder() As String
Dim bInf As BrowseInfo
Dim lItem As Long
Dim sDirName As String
Dim hwnd As Long
bInf.hWndOwner = Me.hwnd
bInf.sDisplayName = Space$(MAX_PATH)
bInf.sTitle = "Select Folder"
bInf.ulFlags = BIF_RETURNONLYFSDIRS
lItem = SHBrowseForFolder(bInf)
If lItem Then
sDirName = Space$(MAX_PATH)
If SHGetPathFromIDList(lItem, sDirName) Then
Browse_Folder = Left(sDirName, InStr(sDirName, Chr$(0)) - 1)
Else
Browse_Folder = ""
End If
End If
End Function

Private Sub countFiles(folderPath As String, recurse As Boolean)
Dim fd As WIN32_FIND_DATA
Dim hFind As Long
Dim strFile As String
Dim strSearch As String
Dim fileSize As Currency
Dim SizeOnDisk As Currency
Dim roundUp As Boolean
Dim strFileName As String
Dim posNull As Long

If Right$(folderPath, 1) <> "\" Then
folderPath = folderPath & "\"
End If
If Left$(folderPath, 4) <> "\\?\" Then
folderPath = "\\?\" & folderPath
End If
strSearch = folderPath & "*"
hFind = FindFirstFile(ByVal StrPtr(strSearch), ByVal VarPtr(fd))
If hFind > 0 Then
Do
' Get the Unicode file name from the UDT and remove the null
strFileName = fd.fileName
posNull = InStr(strFileName, Chr(0))
strFileName = Left(strFileName, posNull - 1)
If ( _
fd.lngFileAttributes And FILE_ATTRIBUTE_DIRECTORY) = _
FILE_ATTRIBUTE_DIRECTORY Then
If strFileName = "." Or strFileName = ".." Then
' ignore these
Else
' It is a directory
folders = folders + 1
If recurse Then
countFiles folderPath & strFileName, recurse
End If
End If
Else
files = files + 1
If (fd.lngFileSizeLow And loMask) <> 0 Then
roundUp = True
Else
roundUp = False
End If
fd.lngReserved0 = fd.lngFileSizeHigh
CopyMemory fileSize, fd.lngFileSizeLow, 8
'
totalSize = totalSize + fileSize
If roundUp Then
fd.lngFileSizeLow = fd.lngFileSizeLow And hiMask
End If
CopyMemory SizeOnDisk, fd.lngFileSizeLow, 8
'
If roundUp Then '
totalSizeOnDisk = totalSizeOnDisk + SizeOnDisk + clusterSize
Else
totalSizeOnDisk = totalSizeOnDisk + SizeOnDisk
End If
End If
Loop While CBool(FindNextFile(hFind, fd))
Call FindClose(hFind)
End If

End Sub

Private Sub Command1_Click()
Dim sfolder As String, s1 As String
Dim t1 As Single, t2 As Single
Dim Sectors As Long, Bytes As Long
Dim FreeC As Long, TotalC As Long
Dim total As Long, Freeb As Long
Command1.Enabled = False
sfolder = Browse_Folder
Me.Refresh: DoEvents
If sfolder = "" Then
Caption = "No Folder Selected"
Else
GetClusterSize Left$(sfolder, InStr(sfolder, "\"))
directories = 0
folders = 0
files = 0
totalSize = 0
totalSizeOnDisk = 0
s1 = Caption: Caption = "Please wait . . ."
t1 = Timer
countFiles sfolder, True
t2 = Timer
Caption = s1
s1 = Format(files, "###,###,##0") & " files, "
s1 = s1 & Format(folders, "###,###,##0") & " folders."
s1 = s1 & vbCrLf & "Total file size = " & Format((totalSize * 10000&), _
"###,###,###,##0")
s1 = s1 & vbCrLf & "Total size on disk = " & Format(( _
totalSizeOnDisk * 10000&), "###,###,###,##0")
s1 = s1 & vbCrLf & "Time taken = " & Format(t2 - t1, _
"###.00") & " seconds."
MsgBox s1
End If
DoEvents
Command1.Enabled = True
End Sub




(nobody)

8/29/2011 12:53:00 PM

0

"Nobody" <nobody@nobody.com> wrote in message
news:j3g1se$33d$1@speranza.aioe.org...
> Here are the minor changes I made:
>
> - FindFirstFile and WIN32_FIND_DATA declaration.
> - Making sure that the path is prefixed with "\\?\". This is not necessary
> if you know that the path will not exceed MAX_PATH, but it's good to use
> nevertheless. This code is near the beginning of countFiles sub.
> - Copying the file name from the byte array to a String variable and
> removing the Null. This code is in the next line after the "Do" loop line.
> - Removed the InStr in the call to countFiles sub since the Null is
> already removed.

Also:

- Added a check for "." and ".." specifically.