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