PDA

View Full Version : File: Binary I/O with different Variable-Types



ReneMiner
01-11-2012, 16:23
a question about binary file In/Output - all examples are displaying just the use of strings or even how to read in a whole file.

I want to read and write different mixed variable types and not just bytes or strings and I'm not sure how to do this:


Example that I use is some vb6-alike pseudocode and not actual thinBasic. the empty parameter-space in put/get- command signals just to write or read the next available value

local i as Long
local myByte(10) as Byte
local myLong(10) as Long
local myDouble(10) as Double
local myString(10) as String

fNum = GetFreeFileHandle

Open "C:\myFile.dat" for binary as fNum

__for i = 1 to 10
____put fnum,,myLong(i)
____put fnum,,myDouble(i)
__next i
__for i = 1 to 10
____put fnum,,myByte(i)
____put fnum,,myString(i) + CRLF
__next i

Close fnum

and now read those values in again the same way, just using "Get fnum,,myValue" instead of "Put fNum,,myValue". How does that work in tB?
Could someone please "translate" this example?

ErosOlmi
01-11-2012, 22:10
Always remember that ALL in computer is just a sequence of bytes.
String are sequences of bytes, numbers (any type) are sequences of bytes.
What differentiate one variable to the other is the meaning we give to them.

That said, you can take advantage of thinBasic binary converting functions called MKxx (http://www.thinbasic.com/public/products/thinBasic/help/html/mkx.htm) (from numeric to string) and CVxx (http://www.thinbasic.com/public/products/thinBasic/help/html/index.html?cvx.htm) (from strings to numeric)

There is just one trick to keep into consideration: for all numeric types we can know their length so reading them back is not a problem (bytes are one byte, long are 4 bytes, ...) but in order to read back dynamic strings, you need to store the original string length. This will allow you to read back the string knowing its length.

Your code can be something like the following but there can be many other ways to store binary info into files depending how you want your data organised into the file.



Uses "file"


Local i As Long


Local myByte(10) As Byte
Local myLong(10) As Long
Local myDouble(10) As Double
Local myString(10) As String


'---Open file for writing in BINARY mode
Long fNum = FILE_Open (APP_SourcePath & "myFile.dat", "BINARY")


For i = 1 To 10
'---Write the binay for of a long
FILE_Put(fNum, MKL$(myLong(i)))
'---Write the binay for of a double
FILE_Put(fNum, MKD$(myDouble(i)))
Next


For i = 1 To 10
'---Write the binay for of a byte
FILE_Put(fNum, MKBYT$(mybyte(i)))

'---For strings, in order to be able to read back, you need to store also string lenght
'---So here we will write a binary long containing the string lenght
'---when we will read it back we will know the len of the subsequent string to read
FILE_Put(fNum, MKL$(Len(myString(i))))
FILE_Put(fNum, myString(i))
Next


FILE_Close(fNum)

ReneMiner
01-11-2012, 22:36
Thank you, this is exactly what I wanted to know. And File_Get() works the same way, I guess?

FILE_Get(fNum, MKD$(myDouble)) ?

-you should add this as an example to the help-file.

ErosOlmi
01-11-2012, 23:05
No

FILE_GET (http://www.thinbasic.com/public/products/thinBasic/help/html/file_get.htm) reads a sequence of bytes (from 1 to up to 2 GB) and return a string. The second parameter of FILE_GET is the number of bytes to read from the file starting from current file position.
To give a meaning of "DOUBLE" to your string (sequence of bytes) you need the contrary of MKD$ that is CVD in this way:



MyDouble = CVD(FILE_GET(FileID, sizeof(Double)))


Mainly you read a binary string of sizeof(double) bytes (that are 4 bytes) and convert them into a real number using CVD (convert double).

Ciao
Eros