From: Karl E. Peterson on
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

"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
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
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
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
> >
> >
>