Results 1 to 14 of 14

Thread: Measure the Size of a Huge File

  1. #1

    Thread Starter
    PowerPoster Code Doc's Avatar
    Join Date
    Mar 2007
    Location
    Omaha, Nebraska
    Posts
    2,354

    Question 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?
    Doctor Ed

  2. #2
    Frenzied Member
    Join Date
    Mar 2009
    Posts
    1,182

    Re: Measure the Size of a Huge File

    Perhaps this may help...

    http://www.vbforums.com/showthread.p...ght=large+file



    Good Luck
    Option Explicit should not be an Option!

  3. #3

    Thread Starter
    PowerPoster Code Doc's Avatar
    Join Date
    Mar 2007
    Location
    Omaha, Nebraska
    Posts
    2,354

    Re: Measure the Size of a Huge File

    Quote Originally Posted by vb5prgrmr View Post
    That helps not. Does anyone who writes VB6 code have the answer?
    Doctor Ed

  4. #4
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    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).
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  5. #5

    Thread Starter
    PowerPoster Code Doc's Avatar
    Join Date
    Mar 2007
    Location
    Omaha, Nebraska
    Posts
    2,354

    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?
    Doctor Ed

  6. #6
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    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.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  7. #7

    Thread Starter
    PowerPoster Code Doc's Avatar
    Join Date
    Mar 2007
    Location
    Omaha, Nebraska
    Posts
    2,354

    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?
    Doctor Ed

  8. #8
    Software Carpenter dee-u's Avatar
    Join Date
    Feb 2005
    Location
    Pinas
    Posts
    11,127

    Re: Measure the Size of a Huge File

    Have you tried FileLen?
    Regards,


    As a gesture of gratitude please consider rating helpful posts. c",)

    Some stuffs: Mouse Hotkey | Compress file using SQL Server! | WPF - Rounded Combobox | WPF - Notify Icon and Balloon | NetVerser - a WPF chatting system

  9. #9

    Thread Starter
    PowerPoster Code Doc's Avatar
    Join Date
    Mar 2007
    Location
    Omaha, Nebraska
    Posts
    2,354

    Re: Measure the Size of a Huge File

    Quote Originally Posted by dee-u View Post
    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.
    Doctor Ed

  10. #10
    PowerPoster
    Join Date
    May 2006
    Location
    Location, location!
    Posts
    2,673

    Re: Measure the Size of a Huge File

    Quote Originally Posted by Code Doc View Post
    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.

  11. #11
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    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.

  12. #12

    Thread Starter
    PowerPoster Code Doc's Avatar
    Join Date
    Mar 2007
    Location
    Omaha, Nebraska
    Posts
    2,354

    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

  13. #13
    PowerPoster isnoend07's Avatar
    Join Date
    Feb 2007
    Posts
    3,237

    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

  14. #14
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    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:
    1. Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    2. 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
    3. Private Declare Function GetFileSize Lib "kernel32" (ByVal hFile As Long, lpFileSizeHigh As Long) As Long
    4.  
    5. ' Currency handles file sizes over 2 gig
    6. ' Thanks to Richard Newcombe from codeguru.com
    7. Public Function GetSize(ByVal File As String) As Currency
    8.     Const GENERIC_READ = &H80000000
    9.     Const FILE_SHARE_READ = &H1
    10.     Const FILE_SHARE_WRITE = &H2
    11.     Const OPEN_EXISTING = 3
    12.     Dim lngHandle As Long
    13.     Dim lngLow As Long
    14.     Dim lngHigh As Long
    15.     Dim curFileSize As Currency
    16.    
    17.     ' Open the file
    18.     lngHandle = CreateFile(File, GENERIC_READ, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0&, OPEN_EXISTING, 0, 0)
    19.     ' Get the file size
    20.     lngLow = GetFileSize(lngHandle, lngHigh)
    21.     CloseHandle lngHandle
    22.     ' Combine the Low and High values into one currency
    23.     ' Must use the '@' currency declaration or IDE will balk
    24.     curFileSize = 4294967295@ * lngHigh
    25.     If lngLow < 0 Then
    26.         curFileSize = curFileSize + (4294967295@ + (lngLow + 1))
    27.     Else
    28.         curFileSize = curFileSize + lngLow
    29.     End If
    30.     GetSize = curFileSize
    31. 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
  •  



Click Here to Expand Forum to Full Width