Handling Files in Visual Basic, Page 5
The binary file mode is the closest you get to writing direct to disk in Visual Basic. It allows you to directly write to a file at a byte-by-byte level.
To be honest, this mode is pretty limited in its uses, but there are times when it could be helpful.
As with the last mode, we use the Get and Put statements to manipulate files. This time we have the syntax:
Put #filenumber, bytenumber, varname
Get #filenumber, bytenumber, varname
You will notice that the difference between using Get and Put for random files is that instead of using a recordnumber as in Random mode, it uses a bytenumber. This "byte number" is the number of bytes into the file that you want to start reading from.
You can see from the diagram above that every byte can be given a byte number. So, the command...
Get #1, 8, MyVar
...will place data from byte number 8 into the variable called 'MyVar'. The amount of data put into 'MyVar' depends on the defined size of the variable.
Now there are two ways you can define the length of a variable:
Dim varname as String * 50
Here, varname is the name of the variable and the number after the asterisk (*) is the length you want the string to be. However, once set, these variables have been declared (Dimmed) cannot be changed in length.
varname = String(lengthofstring, 0)
Here, varname is the name of the variable you want to set the length of, lengthofstring is the length that you want to set the string. 0 means character zero which is a "null" character.
Going back to the Get statement, using the above diagram you should be able to see that...
Get #1, 8, MyVar
... would return 'ORLD' to our 4-byte MyVar variable.
Make sense? Once again, the best way to demonstrate this is via example. So fire up Visual Basic and off we go!
Just One More Example
It's now time to check out the Binary file access mode in action!
Open Visual Basic and double-click on "Standard EXE"
You will be left with a blank form.
Now insert the following code:
Const ChunkSize = 1024'This is the amount (chunk) of data to take each ' time the file is written to.'The larger the quicker but more memory intensive.'Here I have set it to 1024 bytes which equals 1KB.Dim Data As StringPublic Sub Form_Load Open "c:\source" For Binary As #1 'Source Open "d:\destination" For Binary As #2 'Destination Do Until LOF(1) = Loc(1) Or EOF(1) 'Will do this loop until the end of the source file. Data = "" 'Resets the size of the Data string. MsgBox LOF(1) & vbTab & Loc(1) & _ vbTab & LOF(1) - Loc(1) If LOF(1) - Loc(1) < ChunkSize Then 'If there is not enough data left for one chunk. Data = String(LOF(1) - Loc(1), 0) 'Sets the length of the string; Data. Else 'If there is enough data left for one chunk Data = String(ChunkSize, 0) End If Get #1, , Data Put #2, , Data LoopEnd Sub
You won't find any strange new commands in this code, but the concepts may be a little difficult to understand at first. Just remember...
LOF(1) - Loc(1) - Remember that LOF(#filenumber) tells you the length of the file and Loc(#filenumber) is the last read byte. So, by simple maths when you take away the current location (which will be how many bytes have been read) from the length of the file, you will get how many bytes of the file is left.
Chunks - I have read data in as chunks, the size of each chunk is set in the constant ChunkSize. The reason I have taken data in as 1 kilobyte chunks is because if you try to make a variable the size of the source file you end up running out of memory.
Remember I said the uses of binary files were limited? Well, I wasn't lying. But there are times you may want to use them. Such as:
Sam Huggill's Compare the contents of two files - This tip uses the binary file mode to find if two files are the same.
Again Sam Huggill has another gem; Using the Internet Transfer Control: Part 1 - Here Sam uses the Internet Control to get data from a file and outputs it to a binary mode file.
Anyone for Scraps?
And now for all those other bits I almost forgot.
So far, we've used the Open statement like this...
Open pathname For mode As #filenumber [Len=reclength]
... however there are also a couple of other extra widgets that I've not yet mentioned. The official way of using the Open statement is like this...
Open pathname For mode [Access access] [lock] As #filenumber [Len=reclength]
In other words, you have two extra optional arguments there - Access and Lock. Let's explain those now.
[Lock] controls how other programs 'see' your file. [Lock] can be replaced with; Shared, Lock Read, Lock Write, and Lock Read Write, depending on what you want:
What it Does
Allows other programs to read and write to this file.
Allows other programs to write and not read to this file.
Allows other programs to read and not write to this file.
Lock Read Write
(Default) Does not allow other programs to read or write to it.
[Access] controls if your program can write, read, or read & write to your file. [Access] can be replaced with; Read, Write, or Read Write.
What it Does
Allows your program to read from the file
Allows your program to write to the file
(Default) Allows your program to both read and write to the file.
[Access] is useful to stop you from corrupting files that you mean to read from (i.e. typing Get instead of Put). It is a similar practice to Option Explicit which forces you to declare variables.
As an example, this statement...
Open "TESTFILE" For Binary Access Read Lock Read As #1
... opens 'TESTFILE' in Binary mode for reading; other applications cannot read the file due to our lock.