From: RB Smissaert on
Just come across the fact that FileLen has a problem with large files in
that the result will become negative
if the filesize exceeds the range of the Long datatype. Now, will there be
an error if the filesize exceeds twice
the range of the Long datatype? I can't find a file of that size, so I can't
test.
The reason I need to know is to make sure this api code will work with those
large files.
If not then I will just chuck the FileLen out:

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 "FindFirstFileA" _
(ByVal lpFileName As String, _
lpFindFileData As WIN32_FIND_DATA)
As Long
Private Declare Function FindClose Lib "kernel32" _
(ByVal hFindFile As Long) As Long

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 As String * MAX_PATH
cAlternate As String * 14
End Type

Function FileSizeAPI(strFilePath As String) As Variant

Dim hSearch As Long
Dim WFD As WIN32_FIND_DATA

On Error GoTo ERROROUT 'for if strFilePath doesn't exist in FileLen

FileSizeAPI = FileLen(strFilePath)

If FileSizeAPI > 0 Then
Exit Function
End If

'this seems to be the fastest way to get the file handle
'-------------------------------------------------------
hSearch = FindFirstFile(strFilePath, WFD)

If hSearch = -1 Then
FileSizeAPI = -1
Else
FileSizeAPI = LargeInteger(WFD.nFileSizeLow, WFD.nFileSizeHigh)
FindClose hSearch
End If

Exit Function

ERROROUT:
FileSizeAPI = -1

End Function

Public Function LargeInteger(ByVal LoPart As Long, _
ByVal HiPart As Long) As Variant

Dim nResult As Currency

'Copy the parts, appropriately.
CopyMemory ByVal VarPtr(nResult), LoPart, 4
CopyMemory ByVal VarPtr(nResult) + 4, HiPart, 4

'Return the result as VarType Decimal(14).
LargeInteger = nResult * CDec(10000)

End Function


RBS

From: Karl E. Peterson on
RB Smissaert wrote:
> Just come across the fact that FileLen has a problem with large files in
> that the result will become negative
> if the filesize exceeds the range of the Long datatype. Now, will there be
> an error if the filesize exceeds twice
> the range of the Long datatype?

Sure, could be. Depends how you approach it. You can't fit a LARGE_INTEGER into a
Long, of course.

> I can't find a file of that size, so I can't test.

Every developer owes it to themself to become familiar with virtual machines.
You'll have plenty of files that big real soon, then! :-)

> The reason I need to know is to make sure this api code will work with those
> large files.
> If not then I will just chuck the FileLen out:

Why are you using that? I guess what you're asking is whether FileLen() will toss
an error with a really huge file? Hmmm, dunno. I'll try... Nope! Looks like it
just wraps around and around...

?filelen("m:\vms\vista\vistaU-bare.vhd")
-1787076608

From a DIR listing...

01/23/2008 01:36 PM 6,802,857,984 VistaU-Bare.vhd

--
..NET: It's About Trust!
http://vfred.mvps.org


From: RB Smissaert on
Thanks for looking at that and yes, should get a virtual machine really.

> Why are you using that?
Great majority of files passed to the function will be small, so I thought I
might save some time
to try the FileLen first.

> I guess what you're asking is whether FileLen() will toss an error with a
> really huge file?
Exactly, as that would be no good.

> I'll try... Nope! Looks like it just wraps around and around...
OK, thanks and that is no good either, so will need to chuck FileLen out
then.
Maybe FileLen uses that API in any case, so trying FileLen first won't gain
any time in that case.
Will do some timing tests to see if that might be the case.


RBS


"Karl E. Peterson" <karl(a)exmvps.org> wrote in message
news:eYrdgwMZKHA.196(a)TK2MSFTNGP05.phx.gbl...
> RB Smissaert wrote:
>> Just come across the fact that FileLen has a problem with large files in
>> that the result will become negative
>> if the filesize exceeds the range of the Long datatype. Now, will there
>> be
>> an error if the filesize exceeds twice
>> the range of the Long datatype?
>
> Sure, could be. Depends how you approach it. You can't fit a
> LARGE_INTEGER into a Long, of course.
>
>> I can't find a file of that size, so I can't test.
>
> Every developer owes it to themself to become familiar with virtual
> machines. You'll have plenty of files that big real soon, then! :-)
>
>> The reason I need to know is to make sure this api code will work with
>> those
>> large files.
>> If not then I will just chuck the FileLen out:
>
> Why are you using that? I guess what you're asking is whether FileLen()
> will toss an error with a really huge file? Hmmm, dunno. I'll try...
> Nope! Looks like it just wraps around and around...
>
> ?filelen("m:\vms\vista\vistaU-bare.vhd")
> -1787076608
>
> From a DIR listing...
>
> 01/23/2008 01:36 PM 6,802,857,984 VistaU-Bare.vhd
>
> --
> .NET: It's About Trust!
> http://vfred.mvps.org
>

From: Patrice on
The range of a 32 bit integer is 4 Go if I'm not mistaken. So find a file a
bit larger (or just create one) and see how it behaves.

In VB.NET FileLen returns a 64 bit integer and uses cached data readen by
FindFirstFile as well to get the value...

--
Patrice

"RB Smissaert" <bartsmissaert(a)blueyonder.co.uk> a �crit dans le message de
news:%23Jly71KZKHA.5608(a)TK2MSFTNGP05.phx.gbl...
> Just come across the fact that FileLen has a problem with large files in
> that the result will become negative
> if the filesize exceeds the range of the Long datatype. Now, will there be
> an error if the filesize exceeds twice
> the range of the Long datatype? I can't find a file of that size, so I
> can't test.
> The reason I need to know is to make sure this api code will work with
> those large files.
> If not then I will just chuck the FileLen out:
>
> 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 "FindFirstFileA" _
> (ByVal lpFileName As String, _
> lpFindFileData As WIN32_FIND_DATA)
> As Long
> Private Declare Function FindClose Lib "kernel32" _
> (ByVal hFindFile As Long) As Long
>
> 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 As String * MAX_PATH
> cAlternate As String * 14
> End Type
>
> Function FileSizeAPI(strFilePath As String) As Variant
>
> Dim hSearch As Long
> Dim WFD As WIN32_FIND_DATA
>
> On Error GoTo ERROROUT 'for if strFilePath doesn't exist in FileLen
>
> FileSizeAPI = FileLen(strFilePath)
>
> If FileSizeAPI > 0 Then
> Exit Function
> End If
>
> 'this seems to be the fastest way to get the file handle
> '-------------------------------------------------------
> hSearch = FindFirstFile(strFilePath, WFD)
>
> If hSearch = -1 Then
> FileSizeAPI = -1
> Else
> FileSizeAPI = LargeInteger(WFD.nFileSizeLow, WFD.nFileSizeHigh)
> FindClose hSearch
> End If
>
> Exit Function
>
> ERROROUT:
> FileSizeAPI = -1
>
> End Function
>
> Public Function LargeInteger(ByVal LoPart As Long, _
> ByVal HiPart As Long) As Variant
>
> Dim nResult As Currency
>
> 'Copy the parts, appropriately.
> CopyMemory ByVal VarPtr(nResult), LoPart, 4
> CopyMemory ByVal VarPtr(nResult) + 4, HiPart, 4
>
> 'Return the result as VarType Decimal(14).
> LargeInteger = nResult * CDec(10000)
>
> End Function
>
>
> RBS
>

From: Patrice on
> Why restrict yourself to NET?

I would have checked the VB6 FileLen implementation if I knew how to do
this. Since then (I even later searched how to do that), it seems that using
a debugger with the MS Symbol server could be an possible approach to see
how it is done in the VB6 runtime.

> Why not tell him how it's done in Delphi and Java.

My next best choice was .NET because I knew how to check the implementation
in no time. It could have been something else as well if it were the
quickest path for me...

> In fact why restrict yourself to Windows? Why not tell him how it's done
> on a Linux machine or on an Apple Mac?

Because ultimately it calls into the Windows API.

> Let's face it, you're just peddling dotnet! You know very well that NET is
> not the subject of this group.

I just thought that as the OP wanted a replacement for the FileLen function,
it would be interesting to see how it is currently implemented in whatever
implementation I could check.

I never suggested to switch to .NET. I just talked about how it is
implemented in .NET (and because I don't know yet how to check the VB6
implementation). Seems to be a crime here.

Any non technical response (such as finding how FileLen is implemented in
VB6) will now be ignored as precisely my goal is not trolling...

--
Patrice