From: Karl E. Peterson on 17 Nov 2009 17:13 RB Smissaert wrote: > One possible compromise might be: > > If (WFD.nFileSizeHigh = 0) And (WFD.nFileSizeLow > 0) Then > FileSizeAPI = WFD.nFileSizeLow > Else > FileSizeAPI = LargeInteger(WFD.nFileSizeLow, WFD.nFileSizeHigh) > End If > > Yes, that does knock a few percent off. Cool. > Actually, let's make that: > If (WFD.nFileSizeHigh = 0&) And (WFD.nFileSizeLow > 0&) Then Heh... touche' -- ..NET: It's About Trust! http://vfred.mvps.org
From: Schmidt on 18 Nov 2009 03:48 "RB Smissaert" <bartsmissaert(a)blueyonder.co.uk> schrieb im Newsbeitrag news:O81Av$8ZKHA.1592(a)TK2MSFTNGP06.phx.gbl... > Yes, that does knock a few percent off. If you can live with the "restriction", that the routine would work correctly only up to filesizes of about 922 TeraByte, then you could change the return-value of the function to Currency instead of Variant, and another few percentpoints could be gained, if you omit the LargeInteger-SubRoutine-Call, as well as doing the CopyMemory-Call only once (all directly within the FileSizeAPI-Function). The LargeInteger-Routine can then remain as correctly as it currently is, it is just not used anymore... Private Declare Sub CopyMemory _ Lib "kernel32" _ Alias "RtlMoveMemory" (Dest As Any, _ Src As Any, _ ByVal cBytes As Long) Private Declare Function FindFirstFile Lib "kernel32" _ Alias "FindFirstFileW" _ (ByVal lpFileName As Long, _ lpFindFileData As WIN32_FIND_DATA) As Long Private Declare Function FindClose Lib "kernel32" _ (ByVal hFindFile As Long) As Long Private Const MAX_PATH = 260 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(0 To (MAX_PATH * 2) - 1) As Byte cAlternate(0 To 27) As Byte End Type Private Function FileSizeAPI(strFilePath As String) As Currency Dim hSearch As Long Dim WFD As WIN32_FIND_DATA hSearch = FindFirstFile(StrPtr(strFilePath), WFD) If hSearch = -1& Then FileSizeAPI = -1& Else FindClose hSearch WFD.dwReserved0 = WFD.nFileSizeHigh CopyMemory FileSizeAPI, WFD.nFileSizeLow, 8 FileSizeAPI = FileSizeAPI * 10000@ End If End Function Olaf
From: bart.smissaert on 18 Nov 2009 06:04 Hi Olaf, On some quick testing it does work, but it looks to be slower than the last posted code. Doing this at work and will have a better look at home later. RBS On Nov 18, 8:48 am, "Schmidt" <s...(a)online.de> wrote: > "RB Smissaert" <bartsmissa...(a)blueyonder.co.uk> schrieb im Newsbeitragnews:O81Av$8ZKHA.1592(a)TK2MSFTNGP06.phx.gbl... > > > Yes, that does knock a few percent off. > > If you can live with the "restriction", that the > routine would work correctly only up to filesizes > of about 922 TeraByte, then you could change the > return-value of the function to Currency instead of Variant, > and another few percentpoints could be gained, > if you omit the LargeInteger-SubRoutine-Call, > as well as doing the CopyMemory-Call only once > (all directly within the FileSizeAPI-Function). > The LargeInteger-Routine can then remain as > correctly as it currently is, it is just not used anymore... > > Private Declare Sub CopyMemory _ > Lib "kernel32" _ > Alias "RtlMoveMemory" (Dest As Any, _ > Src As Any, _ > ByVal cBytes As Long) > > Private Declare Function FindFirstFile Lib "kernel32" _ > Alias "FindFirstFileW" _ > (ByVal lpFileName As Long, _ > lpFindFileData As WIN32_FIND_DATA) As Long > > Private Declare Function FindClose Lib "kernel32" _ > (ByVal hFindFile As Long) As Long > > Private Const MAX_PATH = 260 > > 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(0 To (MAX_PATH * 2) - 1) As Byte > cAlternate(0 To 27) As Byte > End Type > > Private Function FileSizeAPI(strFilePath As String) As Currency > > Dim hSearch As Long > Dim WFD As WIN32_FIND_DATA > > hSearch = FindFirstFile(StrPtr(strFilePath), WFD) > > If hSearch = -1& Then > FileSizeAPI = -1& > Else > FindClose hSearch > > WFD.dwReserved0 = WFD.nFileSizeHigh > CopyMemory FileSizeAPI, WFD.nFileSizeLow, 8 > FileSizeAPI = FileSizeAPI * 10000@ > End If > > End Function > > Olaf
From: RB Smissaert on 18 Nov 2009 08:40 Hi Olaf, Had a better look now and yes, this knocks a few more percent off, more so when testing on a large file. This is the function I will be using then and thanks for the tip. Function FileSizeAPI(strFilePath As String) As Currency Dim hFind As Long Dim WFD As WIN32_FIND_DATA hFind = FindFirstFile(StrPtr(strFilePath), WFD) If hFind = -1& Then FileSizeAPI = -1@ Else FindClose hFind If (WFD.nFileSizeHigh = 0&) And (WFD.nFileSizeLow > 0&) Then FileSizeAPI = WFD.nFileSizeLow Else WFD.dwReserved0 = WFD.nFileSizeHigh CopyMemory FileSizeAPI2, WFD.nFileSizeLow, 8 FileSizeAPI = FileSizeAPI2 * 10000@ End If End If End Function RBS "Schmidt" <sss(a)online.de> wrote in message news:uCisX0CaKHA.428(a)TK2MSFTNGP06.phx.gbl... > > "RB Smissaert" <bartsmissaert(a)blueyonder.co.uk> schrieb im Newsbeitrag > news:O81Av$8ZKHA.1592(a)TK2MSFTNGP06.phx.gbl... > >> Yes, that does knock a few percent off. > If you can live with the "restriction", that the > routine would work correctly only up to filesizes > of about 922 TeraByte, then you could change the > return-value of the function to Currency instead of Variant, > and another few percentpoints could be gained, > if you omit the LargeInteger-SubRoutine-Call, > as well as doing the CopyMemory-Call only once > (all directly within the FileSizeAPI-Function). > The LargeInteger-Routine can then remain as > correctly as it currently is, it is just not used anymore... > > Private Declare Sub CopyMemory _ > Lib "kernel32" _ > Alias "RtlMoveMemory" (Dest As Any, _ > Src As Any, _ > ByVal cBytes As Long) > > Private Declare Function FindFirstFile Lib "kernel32" _ > Alias "FindFirstFileW" _ > (ByVal lpFileName As Long, _ > lpFindFileData As WIN32_FIND_DATA) As Long > > Private Declare Function FindClose Lib "kernel32" _ > (ByVal hFindFile As Long) As Long > > Private Const MAX_PATH = 260 > > 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(0 To (MAX_PATH * 2) - 1) As Byte > cAlternate(0 To 27) As Byte > End Type > > Private Function FileSizeAPI(strFilePath As String) As Currency > > Dim hSearch As Long > Dim WFD As WIN32_FIND_DATA > > hSearch = FindFirstFile(StrPtr(strFilePath), WFD) > > If hSearch = -1& Then > FileSizeAPI = -1& > Else > FindClose hSearch > > WFD.dwReserved0 = WFD.nFileSizeHigh > CopyMemory FileSizeAPI, WFD.nFileSizeLow, 8 > FileSizeAPI = FileSizeAPI * 10000@ > End If > > End Function > > Olaf > >
From: mayayana on 18 Nov 2009 09:06
If it's worth being extremely efficient, couldn't you also skip the check of the nFileSizeLow? I assume it can't be < 0. If (WFD.nFileSizeHigh = 0&) Then FileSizeAPI = WFD.nFileSizeLow Also, this is slightly OT -- sorry to hijack your thread -- but I wonder if someone could explain why, in an empty folder, FindFirstFile will return 1 valid file handle and 2 names: "." and ".." It's very strange behavior, making it tricky to write just a simple "is the folder empty?" routine. > Function FileSizeAPI(strFilePath As String) As Currency > > Dim hFind As Long > Dim WFD As WIN32_FIND_DATA > > hFind = FindFirstFile(StrPtr(strFilePath), WFD) > > If hFind = -1& Then > FileSizeAPI = -1@ > Else > FindClose hFind > If (WFD.nFileSizeHigh = 0&) And (WFD.nFileSizeLow > 0&) Then > FileSizeAPI = WFD.nFileSizeLow > Else > WFD.dwReserved0 = WFD.nFileSizeHigh > CopyMemory FileSizeAPI2, WFD.nFileSizeLow, 8 > FileSizeAPI = FileSizeAPI2 * 10000@ > End If > End If > > End Function > > > RBS > > > "Schmidt" <sss(a)online.de> wrote in message > news:uCisX0CaKHA.428(a)TK2MSFTNGP06.phx.gbl... > > > > "RB Smissaert" <bartsmissaert(a)blueyonder.co.uk> schrieb im Newsbeitrag > > news:O81Av$8ZKHA.1592(a)TK2MSFTNGP06.phx.gbl... > > > >> Yes, that does knock a few percent off. > > If you can live with the "restriction", that the > > routine would work correctly only up to filesizes > > of about 922 TeraByte, then you could change the > > return-value of the function to Currency instead of Variant, > > and another few percentpoints could be gained, > > if you omit the LargeInteger-SubRoutine-Call, > > as well as doing the CopyMemory-Call only once > > (all directly within the FileSizeAPI-Function). > > The LargeInteger-Routine can then remain as > > correctly as it currently is, it is just not used anymore... > > > > Private Declare Sub CopyMemory _ > > Lib "kernel32" _ > > Alias "RtlMoveMemory" (Dest As Any, _ > > Src As Any, _ > > ByVal cBytes As Long) > > > > Private Declare Function FindFirstFile Lib "kernel32" _ > > Alias "FindFirstFileW" _ > > (ByVal lpFileName As Long, _ > > lpFindFileData As WIN32_FIND_DATA) As Long > > > > Private Declare Function FindClose Lib "kernel32" _ > > (ByVal hFindFile As Long) As Long > > > > Private Const MAX_PATH = 260 > > > > 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(0 To (MAX_PATH * 2) - 1) As Byte > > cAlternate(0 To 27) As Byte > > End Type > > > > Private Function FileSizeAPI(strFilePath As String) As Currency > > > > Dim hSearch As Long > > Dim WFD As WIN32_FIND_DATA > > > > hSearch = FindFirstFile(StrPtr(strFilePath), WFD) > > > > If hSearch = -1& Then > > FileSizeAPI = -1& > > Else > > FindClose hSearch > > > > WFD.dwReserved0 = WFD.nFileSizeHigh > > CopyMemory FileSizeAPI, WFD.nFileSizeLow, 8 > > FileSizeAPI = FileSizeAPI * 10000@ > > End If > > > > End Function > > > > Olaf > > > > > |