|
-
Oct 14th, 2009, 06:41 PM
#1
Thread Starter
PowerPoster
Measure the Size of a Huge File
I have a file on my hard drive that exceeds 2^31 bytes. LOF() cannot measure its exact size and errors out.
How can I measure its size to the exact byte using VB6 code? Any suggestions?
-
Oct 14th, 2009, 06:51 PM
#2
Frenzied Member
Re: Measure the Size of a Huge File
Option Explicit should not be an Option!
-
Oct 16th, 2009, 06:08 PM
#3
Thread Starter
PowerPoster
Re: Measure the Size of a Huge File
 Originally Posted by vb5prgrmr
That helps not. Does anyone who writes VB6 code have the answer?
-
Oct 16th, 2009, 06:28 PM
#4
Re: Measure the Size of a Huge File
Code Doc, have you tried one of the solutions at that link? Especially post #2, function: API_FileSize, but gotta use API_OpenFile first to get a file handle and don't forget to close that handle when done.
VB cannot do this by itself. You will need APIs to read the huge file sizes. Pretty much all the examples about use the same code (some tweaked here and there).
-
Oct 16th, 2009, 06:57 PM
#5
Thread Starter
PowerPoster
Re: Measure the Size of a Huge File
Keith said, "VB cannot do this by itself. You will need APIs to read the huge file sizes."
----------------
What if I told you that I think typical VB6 code, without using an API crutch, can measure to within one byte on one passthrough on a file between 2^31 and 2 * 2^31 in size? Would anyone here believe me?
-
Oct 16th, 2009, 09:03 PM
#6
Re: Measure the Size of a Huge File
My opinion only....
There are limitations to the (2147483648# * 2) + FileLen(largeFile) formula. Best to simply use one reliable method that works for all file sizes: APIs.
P.S. I never considered APIs a crutch. I believe without APIs and TLBs, VB would have died a long time ago.
-
Oct 16th, 2009, 10:36 PM
#7
Thread Starter
PowerPoster
Re: Measure the Size of a Huge File
OK, I admit that some APIs are great, even if many are poorly documented. Suppose we know that MyHugeFile exceeds 2^31 - 1 bytes. Take a look at this:
Code:
Private Sub Command1_Click()
Dim RNum As Long, FileSize As Currency, Buffer As String * 1
RNum = 2 ^ 31 - 1
FileSize = RNum - 1
Open "MyHugeFile" For Random As #1 Len = 1
Get #1, RNum, Buffer
Do Until EOF(1)
Get #1, , Buffer
FileSize = FileSize + 1
Loop
MsgBox "File Length = " & FileSize
End Sub
Sure, it might be slow, but will it work?
-
Oct 16th, 2009, 10:47 PM
#8
Re: Measure the Size of a Huge File
-
Oct 17th, 2009, 06:49 AM
#9
Thread Starter
PowerPoster
Re: Measure the Size of a Huge File
 Originally Posted by dee-u
Have you tried FileLen?
FileLen is limited in size to long integer, < 2^31, similar to LOF(), and so is the record number of Get. Note that the code in Post #7 avoids that, unless the record number is implied.
-
Dec 16th, 2009, 12:45 PM
#10
PowerPoster
Re: Measure the Size of a Huge File
 Originally Posted by Code Doc
Sure, it might be slow, but will it work?
I see no-one has commented on it since, so you've not really got much help. If you're hell-bent on not using APIs (I myself rarely do, I don't know most of them either) then I'd guess your code would work fine (I have no idea for definite and don't have a file large enough to test with :-P)...however, one slight speed improvement suggestion for you:
Rather than getting it to the exact byte, get it to the nearest 1MB first by setting the buffer size...when you have a basic idea then repeat it but get it to the nearest 1k then repeat again down to the nearest byte, each time using the starting point gained by the previous iteration. That way if it's 10GB larger than the max you haven't done 10*1024*1024*1024 iterations...instead, you've done a hell of a lot fewer (and test this out by counting the iterations with your method and this suggestion's method :-)).
I don't know figures, but I'm guessing you'd use exponentially fewer iterations to get the same result, and you could even add a GB iteration first if you KNOW the file is likely to be many gigabytes larger than the max filesize you start with. You could possibly also try making use of ON ERROR to try to access points within the file that are beyond the file's length and through process of elimination you'd eventually chance upon the filesize.
Just a few suggestions that I hope are of use, they're suggestions I'd try if I required what you're after :-)
Edit: If I can be bothered I could have a go at making a function for you that'd do it if you need help with it...give me an idea in gigabytes of the filesize you're working with so I can make space and generate a file to test with :-)
Well, everyone else has been doing it :-)
Loading a file into memory QUICKLY - Using SendKeys - HyperLabel - A highly customisable label replacement - Using resource files/DLLs with VB - Adding GZip to your projects
Expect more to come in future
If I have helped you, RATE ME! :-)
I love helping noobs with their VB problems (probably because, as an amateur programmer, I am only slightly better at VB than them :-)) but if you SERIOUSLY want to get help for free from a community such as VBForums, you have to first have a grounding (basic knowledge) in VB6, otherwise you're way too much work to help...You've got to give a little if you want to get help from us, in other words!
And we DON'T do your homework. If your tutor doesn't teach you enough to help you make the project without his or her help, FIND A BETTER TUTOR or try reading books on programming! We are happy to help with minor things regarding the project, but you have to understand the rest of it if you want our help to be useful.
-
Dec 16th, 2009, 05:49 PM
#11
Re: Measure the Size of a Huge File
If you're willing to live with the loss of precision from scaling the value to a whole number Currency value you can use a single API call on the file by name. This example shows two ways to convert the size to a whole Currency value:
Code:
Option Explicit
Private Const GetFileExInfoStandard As Long = 0&
Private Type WIN32_FILE_ATTRIBUTE_DATA_SPECIAL
dwFileAttributes As Long
ftTimes(0 To 23) As Byte
nFileSizeHigh As Long
nFileSizeLow As Long
End Type
Private Type FLIP_CURR
nFileSizeLow As Long
nFileSizeHigh As Long
End Type
Private Type CURR_RESULT
Result As Currency
End Type
Private Declare Function GetFileAttributesEx Lib "kernel32" _
Alias "GetFileAttributesExW" ( _
ByVal lpFileName As Long, _
ByVal fInfoLevelId As Long, _
ByVal lpFileInformation As Long) As Long
Private Function FileSize1(ByVal FileName As String) As Currency
Dim FADS As WIN32_FILE_ATTRIBUTE_DATA_SPECIAL
Dim FC As FLIP_CURR
Dim RES As CURR_RESULT
If GetFileAttributesEx(StrPtr(FileName), GetFileExInfoStandard, VarPtr(FADS)) = 0 Then
Err.Raise Err.LastDllError, "FileSize", "System error"
Else
FC.nFileSizeLow = FADS.nFileSizeLow
FC.nFileSizeHigh = FADS.nFileSizeHigh
LSet RES = FC
FileSize1 = RES.Result * 10000@
End If
End Function
Private Function FileSize2(ByVal FileName As String) As Currency
Dim FADS As WIN32_FILE_ATTRIBUTE_DATA_SPECIAL
If GetFileAttributesEx(StrPtr(FileName), GetFileExInfoStandard, VarPtr(FADS)) = 0 Then
Err.Raise Err.LastDllError, "FileSize", "System error"
Else
FileSize2 = CCur(FADS.nFileSizeHigh) * 4294967296@ + CCur(FADS.nFileSizeLow)
End If
End Function
Private Sub Main()
MsgBox FileSize1("C:\Windows\notepad.exe")
MsgBox FileSize2("C:\Windows\notepad.exe")
End Sub
People often cringe at LSet, but it can be clearer and harder to screw up than using CopyMemory.
-
Dec 16th, 2009, 07:26 PM
#12
Thread Starter
PowerPoster
Re: Measure the Size of a Huge File
I will try your code immediately and report back as soon as I can. Thank you, D, for posting this possible solution.
If I can use Currency pointers to access the contents of this random access file, it suddenly becomes very useful to several of my Apps.
Last edited by Code Doc; Dec 16th, 2009 at 07:50 PM.
Doctor Ed
-
Dec 16th, 2009, 07:43 PM
#13
Re: Measure the Size of a Huge File
I use this code to get space available on large drives with modification it could be used for file size:
http://www.developerfusion.com/code/...-large-drives/
Waiting for a full featured smart phone with out marrying a provider
Go Android
Go raiders 
-
Dec 17th, 2009, 10:07 AM
#14
Re: Measure the Size of a Huge File
Here's the FileSize() method in my XP library, which of course handles files >2gig. (As do all the drive size methods, obviously.) I'm not going to bother adding in hungarian notation, which I do not use in the XP library to make the interface more intuitive.
vb Code:
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Any, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function GetFileSize Lib "kernel32" (ByVal hFile As Long, lpFileSizeHigh As Long) As Long
' Currency handles file sizes over 2 gig
' Thanks to Richard Newcombe from codeguru.com
Public Function GetSize(ByVal File As String) As Currency
Const GENERIC_READ = &H80000000
Const FILE_SHARE_READ = &H1
Const FILE_SHARE_WRITE = &H2
Const OPEN_EXISTING = 3
Dim lngHandle As Long
Dim lngLow As Long
Dim lngHigh As Long
Dim curFileSize As Currency
' Open the file
lngHandle = CreateFile(File, GENERIC_READ, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0&, OPEN_EXISTING, 0, 0)
' Get the file size
lngLow = GetFileSize(lngHandle, lngHigh)
CloseHandle lngHandle
' Combine the Low and High values into one currency
' Must use the '@' currency declaration or IDE will balk
curFileSize = 4294967295@ * lngHigh
If lngLow < 0 Then
curFileSize = curFileSize + (4294967295@ + (lngLow + 1))
Else
curFileSize = curFileSize + lngLow
End If
GetSize = curFileSize
End Function
This is about as fast and easy as it gets.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|