jgore
asked on
Binary File Input/Output.
Heres my problem:
I have a routine that gives me variable length binary data. I wish to store that in a small file and
then read it back. I don't want to use Random file access because of the fixed length read/write;
The binary file must be smaller than that. Here is what I tried (It doesn't work):
Open OutFile For Binary As #1 ' Open Output File
Put #1, ,MyData1 ' Variable Length Binary Data
Put #1, ,MyData2
Put #1, ,MyData3
Close #1 ' Close Input
Open InFile For Binary As #1
' What do I do here?
' if I use Mystring = Input(1,#1)
' then I will only get one char or byte.
' I need to read in each string of binary data as it was written!
' You can't use record numbers in binary mode, just in Random (fixed length)mode.
Close #1
I have a routine that gives me variable length binary data. I wish to store that in a small file and
then read it back. I don't want to use Random file access because of the fixed length read/write;
The binary file must be smaller than that. Here is what I tried (It doesn't work):
Open OutFile For Binary As #1 ' Open Output File
Put #1, ,MyData1 ' Variable Length Binary Data
Put #1, ,MyData2
Put #1, ,MyData3
Close #1 ' Close Input
Open InFile For Binary As #1
' What do I do here?
' if I use Mystring = Input(1,#1)
' then I will only get one char or byte.
' I need to read in each string of binary data as it was written!
' You can't use record numbers in binary mode, just in Random (fixed length)mode.
Close #1
Question is already been posted
You can use this code to read the entire file and put it in a binary array variable:
Dim FContents() as Byte
'Read the file contents using binary input
Open FileName For Binary Access Read As #1
FContents = InputB(LOF(1), 1)
Close 1
As far as I know, you can not determine how binary data was written to the file, I mean the size of each data segment. This is only possible with text read/write using Write #1, and Input #1.
Hope that helps.
Regards
Dim FContents() as Byte
'Read the file contents using binary input
Open FileName For Binary Access Read As #1
FContents = InputB(LOF(1), 1)
Close 1
As far as I know, you can not determine how binary data was written to the file, I mean the size of each data segment. This is only possible with text read/write using Write #1, and Input #1.
Hope that helps.
Regards
ASKER
I guess that would be a good way to do it if I was dealing with small
binary files. But, I am trying to read 20 megabyte files, or bigger,one line at a time.
Just as it was written.
I just thought there might be a way to do it with regular Binary Open.
Why would they have that if you can't read the data back as you put it in?
Visual Online Books even sais that it's a good way to store binary data
in small files but that you have to read the data back sequentially.
They don't explain how to do it!
binary files. But, I am trying to read 20 megabyte files, or bigger,one line at a time.
Just as it was written.
I just thought there might be a way to do it with regular Binary Open.
Why would they have that if you can't read the data back as you put it in?
Visual Online Books even sais that it's a good way to store binary data
in small files but that you have to read the data back sequentially.
They don't explain how to do it!
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
OK, that looks like it would work!
I'll try that and see if the file gets too big because I'm adding
the Length of each string as an integer.
I give you a "A" because it's the first real answer I've had yet that would work.
But, what does Visual Online Books mean when they say("Using Binary File Access"):
"The drawback to binary input/output with variable-length fields is that you can’t access records randomly — you must access records sequentially to learn the length of each record."
Do they mean that I have to write the Length per your example?
Which isn't so bad, but if there is a better way..................;-)
I'll try that and see if the file gets too big because I'm adding
the Length of each string as an integer.
I give you a "A" because it's the first real answer I've had yet that would work.
But, what does Visual Online Books mean when they say("Using Binary File Access"):
"The drawback to binary input/output with variable-length fields is that you can’t access records randomly — you must access records sequentially to learn the length of each record."
Do they mean that I have to write the Length per your example?
Which isn't so bad, but if there is a better way..................;-)
I think Books Online meant to add "How to do this is left as an exercise for the reader." :-)
I have to assume they meant either of the methods I mentioned, or else writing a data type which is self-descriptive (my term for a variable which has a header which gives its length). I didn't mention self-descriptive data because it's more complicated to explain and boils down to the same thing as the example I gave. The more I think about it, though, it's at least worth mentioning.
The most useful example of self-descriptive data would be that of a variable length string. In Binary file mode VB doesn't write the header for a string, just the data. However if you write a user-defined type conatining a string, or write an array of strings, then VB is forced to write the header information. For example -
Dim MyData(0) as String
MyData(0) = "some data"
Put #1,,MyData
and then read with
Get #1,,MyData
Because MyData() is an array of variable-length strings (even though it only has one element) VB will write the string length before the data. As a result, the actual output file created will be identical to the file created by the method I described in my answer, VB just writes the data length for you. The drawback is this only works with a string, not with a byte array or any other sort of data.
If you want to write the data a litle more quickly, you can Dim the string array to more elements and write it all at once, but when you read it back you'd either need to read the strings one at a time or else properly Dim the array you are reading into. However, if you place an array inside a user-defined type or inside a variant then VB will write the entire array header. This adds to the file length but is useful if you don't know the dimensions of the array beforehand (i.e. you can Dim MyData() then Get #1,,MyData and it will figure out how many elements are in the array). It's also useful for arrays other than string arrays.
I hope I haven't confused you too much.. just ask if I haven't explained something well enough, it's late :-)
I have to assume they meant either of the methods I mentioned, or else writing a data type which is self-descriptive (my term for a variable which has a header which gives its length). I didn't mention self-descriptive data because it's more complicated to explain and boils down to the same thing as the example I gave. The more I think about it, though, it's at least worth mentioning.
The most useful example of self-descriptive data would be that of a variable length string. In Binary file mode VB doesn't write the header for a string, just the data. However if you write a user-defined type conatining a string, or write an array of strings, then VB is forced to write the header information. For example -
Dim MyData(0) as String
MyData(0) = "some data"
Put #1,,MyData
and then read with
Get #1,,MyData
Because MyData() is an array of variable-length strings (even though it only has one element) VB will write the string length before the data. As a result, the actual output file created will be identical to the file created by the method I described in my answer, VB just writes the data length for you. The drawback is this only works with a string, not with a byte array or any other sort of data.
If you want to write the data a litle more quickly, you can Dim the string array to more elements and write it all at once, but when you read it back you'd either need to read the strings one at a time or else properly Dim the array you are reading into. However, if you place an array inside a user-defined type or inside a variant then VB will write the entire array header. This adds to the file length but is useful if you don't know the dimensions of the array beforehand (i.e. you can Dim MyData() then Get #1,,MyData and it will figure out how many elements are in the array). It's also useful for arrays other than string arrays.
I hope I haven't confused you too much.. just ask if I haven't explained something well enough, it's late :-)
Use:
Const Len = BytesToReadFromFile
Dim Var as string * Len
GET #f,bytePos,var
This read from file #f Len bytes from bytePos.
Note: Len must be equal less than 65535, so use two times at least to read from big files, such as yours.
Const Len = BytesToReadFromFile
Dim Var as string * Len
GET #f,bytePos,var
This read from file #f Len bytes from bytePos.
Note: Len must be equal less than 65535, so use two times at least to read from big files, such as yours.