Reading byte data

BlitzMax Forums/BlitzMax Programming/Reading byte data

Henri(Posted 2012) [#1]
Hello all,

I'm trying to find out what is efficient way to read byte data from stream when target size is not know. The start situation is that I have a binary file that is made of 10 blocks and I want to store each block in my own custom type's field like:

Type sometype

    field b:byte[]

endtype


Any thought on this one ?

-Henri


Derron(Posted 2012) [#2]
Just read it byte per byte.

	Function ProcessFile(file:string = "file.txt")
		If FileSize(file) <= 0 Then Return 0

		Local dataStream:TStream = ReadStream(file)

		'if you want to skip file headers eg. first 100 bytes
		'Local pos:Int = 100
		'dataStream.seek(pos)

		local byteRead:byte = 0
		'local currentPos:int = 0	
		While Not dataStream.Eof()
			'currentPos = dataStream.pos()
			byteRead = dataStream.ReadByte()
		Wend
	End Function


If you know how long certain blocks will be, you can store the bytes in pre-created banks for further usage.

local bank:TBank = CreateBank( fileSize(file) )
PokeByte(bank, (pos-1)*2,byteRead) 'at pos (n-1)*2

'if you eg want to read a float:
PokeByte(bank, 0,ByteA)
PokeByte(bank, 2,ByteB)
PokeByte(bank, 4,ByteC)
PokeByte(bank, 6,ByteD)
'a float has 8 bytes in bmax
local myFloat:float = PeekFloat( bank, 0 )



Hope that helps a bit.

bye
Ron

Edit: added "End Function"

Last edited 2012


Henri(Posted 2012) [#3]
What I currently have is:

Local src:String = "Binary.file"
Local str:TStream = OpenFile(src,True,True)

Local char:Int
Local bank:TBank = CreateBank()
Local objStr:TStream = CreateBankStream(bank)

... some arbiture code here ...

'Loop all 10 blocks
For Local myobj:TObject = EachIn TObject.list

	'Seek start of the block in binary file
	SeekStream(str,myobj.offset)

	Repeat
		char = ReadByte(str)
		WriteByte(objStr,char)
		
		'When end of the block is reached
		If char = 0
		
			'Set the size of byte array
			myobj.b = New Byte[StreamSize(objStr)]
			
			'Get every byte from our bankstream
			For Local i:Int = 0 To StreamSize(objStr)-1
				myobj.b[i] = ReadByte(objStr)
			Next
			
			CloseStream(objStr)
			Exit
			
		EndIf
			
	Forever
Next	

Type Tobj
	Field offset:int
	Field b:Byte[]
	Global list:tlist
EndType


I don't know if this creates memory leaks sense there is no Freebank command ?

-Henri

Last edited 2012

Last edited 2012


Derron(Posted 2012) [#4]
You work with Blitzmaxobjects, they should take care themselves.

Just set a bank = null and it should get freed on next gc-cycle.


bye
Ron


Henri(Posted 2012) [#5]
That is just what I was wondering, thank you.

-Henri


Alberto-Diablo(Posted 2012) [#6]
If you need for easy loading of data, such as reading the file header, here's an option:

Type THeader
    Field ident:Int
    Field magic:Int
    Field a:Int
    '...
End Type

Local header:THeader = New THeader

Local stream:TStream = ReadStream("file.txt")

stream.Read(header, SizeOf(THeader))


if a particular object to restore erase it here: http://blitzmax.com/codearcs/codearcs.php?code=2979