Getting Directory Size SPEED Question

Just starting out? Need help? Post your questions and find answers here.
yrreti
Enthusiast
Enthusiast
Posts: 546
Joined: Tue Oct 31, 2006 4:34 am

Getting Directory Size SPEED Question

Post by yrreti »

You can use ExamineDirectory recursivly and DirectoryEntrySize to get the size of all items
found under a directory, includng any files found in sub directories. And it is fairly fast.
But if the directory is large, and you are using an anti virus program, which most people are.
Then this method can take 'significantly' longer the first time you run it on that directory.
It is obvious that the anti virus program is examining each file as you access it the first time
to get the file size. I have noticed that Windows Explorer using Right Click and selecting
Properties will do the same thing on the 'first' time. My question is. Is there anyway to get
the directory size in a better way that will work faster and not be affected by the anti virus program?
Or is there just a faster way of doing this then using the ExamineDirectory recursivly and
DirectoryEntrySize method that some one has found?

Thanks for any ideas or suggestions.
c4s
Addict
Addict
Posts: 1981
Joined: Thu Nov 01, 2007 5:37 pm
Location: Germany

Re: Getting Directory Size SPEED Question

Post by c4s »

For Windows you can use GetDiskFreeSpaceEx_(). I think it also works for directories.
If any of you native English speakers have any suggestions for the above text, please let me know (via PM). Thanks!
User avatar
Rings
Moderator
Moderator
Posts: 1435
Joined: Sat Apr 26, 2003 1:11 am

Re: Getting Directory Size SPEED Question

Post by Rings »

no, it returns only the complete diskspace:

Code: Select all

lpFreeBytesAvailable.q
lpTotalNumberOfBytes.q
lpTotalNumberOfFreeBytes.q

Path$=GetEnvironmentVariable("programfiles") ;"c:\windows\system32"
Debug Path$

Result=GetDiskFreeSpaceEx_(Path$,@lpFreeBytesAvailable,@lpTotalNumberOfBytes,@lpTotalNumberOfFreeBytes)
Debug Result
Debug lpFreeBytesAvailable
Debug lpTotalNumberOfBytes
Debug lpTotalNumberOfFreeBytes
SPAMINATOR NR.1
yrreti
Enthusiast
Enthusiast
Posts: 546
Joined: Tue Oct 31, 2006 4:34 am

Re: Getting Directory Size SPEED Question

Post by yrreti »

Thanks for the replies.

I was experimenting with the following to try to see if I could find a faster and less intrusive
method of getting individual file sizes:

Code: Select all

;msdn.microsoft.com info on WIN32_FIND_DATA Structure
;     nFileSizeHigh
;     The high-order DWORD value of the file size, in bytes.
;     This value is zero unless the file size is greater than MAXDWORD.
; 
;     The size of the file is equal To (nFileSizeHigh * (MAXDWORD+1)) + nFileSizeLow.
;
;     nFileSizeLow
;     The low-order DWORD value of the file size, in bytes.

;  Structure WIN32_FIND_DATA
;         dwFileAttributes As IO.FileAttributes
;         ftCreationTime As FILETIME
;         ftLastAccessTime As FILETIME
;         ftLastWriteTime As FILETIME
;         nFileSizeHigh As Integer
;         nFileSizeLow As Integer
;         dwReserved0 As Integer
;         dwReserved1 As Integer
;         ;<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> _
;         cFileName As String
;         ;<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=14)> _
;         cAlternate As String
;  End Structure


dwFileAttributes.l
ftCreationTime.l
ftLastAccessTime.l
ftLastWriteTime.l
nFileSizeHigh.i  ;<-----------------
nFileSizeLow.i  ;<-----------------
dwReserved0.i
dwReserved1.i
cFileName.s
cAlternate.s
 
;test directory with some different size files added for testing
Directory$ = "H:\_test3\*.*"

hFind = FindFirstFile_(@Directory$, @find.WIN32_FIND_DATA)
If hFind
  Repeat
    Debug PeekS(@find\cFileName[0], #MAX_PATH)  ;works.  displays file name
    ;Debug PeekS(@find\cAlternate[0], #MAX_PATH) ;works. (displays dos name format if name is over 8.3)
    ;Debug PeekL(@find\dwFileAttributes)         ;works. just have to convert # to attribute name
    ;Debug PeekL(@find\ftCreationTime)           ;and have no idea how to convert to readable time
    ;assume use something like FileTimeToSystemTime_(PeekL(@find\ftCreationTime),LPSYSTEMTIME)
    ;Debug PeekL(@find\ftLastAccessTime)       ;as above
    ;Debug PeekL(@find\ftLastWriteTime)         ;as above
    
    Debug PeekI(@find\nFileSizeHigh)    ;? always get 0 ?  
    Debug PeekI(@find\nFileSizeLow)  ;works with file sizes up to 999,999,999 , but then 
                                     ;displays a - number thats wrong.
                          ;eg:  a test file that has a size of 2.70 GB (2,900,602,880 bytes)
                          ;will give a value of -1394364416
    
  Until FindNextFile_(hFind, @find.WIN32_FIND_DATA) = 0

  FindClose_(hFind)
EndIf
I never could really understand these Microsoft structures that well. But that's because I rarely
use them. The nFileSizeLow works with file sizes up to 999,999,999, but then gives negative numbers.
The nFileSizeHigh always gets a 0 ? I suspect that these values are suppose to be combined somehow,
and that nFileSizeHigh should have some value for larger numbers.
It would be nice to know how to display the correct time above too, but is there anything wrong with the
way I'm using this concerning nFileSizeLow and nFileSizeHigh? And how do you combine them?

Thanks for your help
Pupil
Enthusiast
Enthusiast
Posts: 715
Joined: Fri Apr 25, 2003 3:56 pm

Re: Getting Directory Size SPEED Question

Post by Pupil »

Use a quad for the file size instead..

something like this should display correct size:

Code: Select all

debug PeekQ(@find\nFileSizeHigh)
Post Reply