| 
                                         Tips
                                        and Tricks: Binary File Access 
                                        Author:
                                        Jack Hoxley 
                                        Written: 3rd May 2001 
                                        Contact: [EMail] 
                                         
                                        Contents
                                        of this lesson 
                                        1. Introduction 
                                        2. How to use binary file access 
                                         
                                        1.
                                        Introduction 
                                        Depending
                                        on your experience with the visual basic
                                        language you may or may not have come
                                        across binary file access (you would
                                        know if you had!), but assuming you know
                                        anything about file input/output using
                                        VB you'll want to know about binary
                                        files. 
                                        As a
                                        particular example, games. Games are
                                        increasingly becoming data driven -
                                        which is a good thing in many ways (but
                                        not the topic of this article), but it
                                        means that vast amounts of data are
                                        stored in external files, this creates
                                        two problems, loading times have to be
                                        tuned perfectly if large amounts of data
                                        must be loaded, and large amounts of
                                        data must be stored (ie, lots of space
                                        required). Whilst there is never any
                                        perfect solution to the speed versus
                                        size problem, binary file access does a
                                        pretty good job at both. 
                                        Take
                                        the constant Pi for example,
                                        3.1415926535898 (13 decimal places).
                                        using normal string output methods
                                        (Write# and Print#) it would logically
                                        take up 15 characters, where 1 character
                                        is 1 byte - 15 bytes have to be stored.
                                        However, you should also be aware that
                                        internally Pi would be of type
                                        "Single", a 32bit floating
                                        point number - 32bit indicating 4 bytes
                                        of memory (8 bits to a byte). So we have
                                        this large number taking up 4 bytes of
                                        system memory yet 15 bytes in our file.
                                        You don't need to be a genius to know
                                        that this isn't very efficient - the
                                        saved version is 3.75 times larger!
                                        You'll never guess what... Binary file
                                        access allows us to only save it as 4
                                        bytes. 
                                         
                                        2.
                                        How to use binary file access 
                                        So you
                                        want to know how to play with this
                                        feature now! luckily for you it's
                                        extremely simple, first time around may
                                        be slightly confusing - but it's easy
                                        after that. 
                                        For
                                        this article, we are going to go about
                                        saving and loading two arrays - one
                                        32bit floating point array (singles),
                                        the other 16bit integers (integer).
                                        Here's the amazingly complex code that
                                        does the trick: 
                                        
                                          
                                          
                                            
                                              
                                                
                                                  
                                                    
                                                      
                                                        
                                                          
                                                            
                                                              
                                                                
                                                                  
                                                                    
                                                                      
                                                                        
                                                                          Dim sngArr(0 To 999) As Single '4000 bytes
Dim intArr(0 To 999) As Integer '2000 bytes
Dim I As Long
'##Fill the arrays with stuff
For I = 0 To 999
    sngArr(I) = Rnd
    intArr(I) = CInt(Rnd * 30000)
Next I
Open "C:\Example.dat" For Binary Access Write As #19
    Put #19, , sngArr
    Put #19, , intArr
Close #19
Open "C:\Example.dat" For Binary Access Read As #21
    Get #21, , sngArr
    Get #21, , intArr
Close #21
                                                                         | 
                                                                       
                                                                    
                                                                   
                                                                 | 
                                                               
                                                            
                                                           
                                                         | 
                                                       
                                                    
                                                   
                                                 | 
                                               
                                            
                                           
                                          
                                         
                                         
                                        greatly
                                        complicated isn't it! There are a few
                                        things to bare in mind; when writing the
                                        data VB will effectively dump the memory
                                        onto the hard drive, if the array is a
                                        64mb monster, so will the file. The most
                                        important part is when reading the file
                                        - it has to be done in the correct order
                                        if you want the correct results, the
                                        "Get #21,,sngArr" line will
                                        read in the first 4000 characters in the
                                        file and convert them into 1000 singles,
                                        you're only going to get an error if
                                        there's not enough data, but you are
                                        going to get some funny results if the
                                        first 4000 characters were originally
                                        2000 integers, you'll effectively end up
                                        with 2 integers stored in one single -
                                        leading to some strange numbers
                                        (compared with what you might of
                                        expected to get). Now we need to delve
                                        into the specifics:
                                        All of
                                        the specific and extended details for
                                        this topic can be found in the MSDN/help
                                        files. highlight the word
                                        "Binary" and hit F1 - follow
                                        the links to the MSDN, and you'll get a
                                        full listing of everything you need to
                                        know. As a quick summary of what you
                                        need to know, I've drawn up the
                                        following list: 
                                        • The
                                        missing parameter in the "Get"
                                        line is the byte offset into the file;
                                        if you know that you need to start
                                        reading the integers from character 2000
                                        then you put that number in here, if
                                        it's left as nothing (like in our
                                        example) then reading begins at the
                                        current position (the beginning if the
                                        file was just opened, or the bytes after
                                        the previous one read). 
                                        • Likewise, the missing parameter in
                                        the "Put" line indicates the
                                        position that writing starts from. You
                                        can use this to overwrite existing data. 
                                        • The line that opens the file has
                                        many combinations of parameters, the
                                        "Access..." part can either be
                                        "Read", "Write" or
                                        "Read Write". 
                                        • The filename must exist if reading,
                                        if it doesn't exist when you open a file
                                        for writing it will be created 
                                        • The File number #21 or #19 used can
                                        be determined using the FreeFile
                                        statement, or you can guess a number
                                        between 1 and 511 (not very professional
                                        though) 
                                         
                                        There!
                                        Your whirlwind tour of binary file
                                        reading and writing is now complete, it
                                        wasn't too hard was it... As a side
                                        note, I ONLY ever use binary access,
                                        with the exception of log files, where
                                        the Print and Write statements are more
                                        useful. Binary files save lots and lots
                                        of space, and are much faster to load
                                        from...
                                        |