Read/Write Array to disk

Blitz3D Forums/Blitz3D Beginners Area/Read/Write Array to disk

xlsior(Posted 2004) [#1]
Hi,

I have a (320,240) array of data that I need to write to and read from disk. What is the most efficient way of doing this?

This is an integer array, where each value is either 0 or 1.
I currently convert these to a single binary string that where each position is a binary value of either CHR$(0) or CHR$(255). This gets written to disk, and loaded again.
This means I end up with a single string with 76800 positions that then get parsed out into an array again:

For x=0 To 319
  For y=0 To 239
    If Mid$(GfxOverlay$(2),(x+1)+(y*320),1)=Chr$(255)Then
      walkability(x,y)=1
    Else
      walkability(x,y)=0
    End If
  Next
Next


The time it takes to write the info to disk is not very important (It is game level information, which gets created once, but loaded many times) The time it takes to load the data from disk and rebuild the original array does need to be as short as possible though.

Is there a faster/better way or writing a full array, or am I on the right track? I *figure* it will be faster to load a 77K string in one go and parse it out, than 77K individual variable reads... But I may be missing something entirely here.

Thoughts, anyone?


ford escort(Posted 2004) [#2]
why don't you just use writebyte and readbyte

;
;save
;

fileout=writefile(filename$)
for x=0 to 319
for y=0 to 239
   writebyte(fileout,myaray(x,y))
next
next
closefile fileout

;
;load
;

filein=readfile(filename$)
for x=0 to 319
for y=0 to 239
   myaray(x,y)=readbyte(filein)
next
next
closefile filein


so no need to convert anything to any other thing = gain of speed !!


xlsior(Posted 2004) [#3]
I haven't clocked this yet, but I do know that in other (older) languages it could be *insanely* slow to read a byte at a time from disk - loading a larger chunk all at once could sometimes be thousands of times faster, hence my conversion to a string first...

Anyway, I guess I'll do some benchmarking. :-?


pjd(Posted 2004) [#4]
your o/s will read the file in chunks, not a byte at a
time so no need to worry about that.


Warren(Posted 2004) [#5]
If you're concerned about load times, write it out as 320 strings of 240 characters each. Then you can read them back in a line at a time (and then break the string down once you've read it in).


eBusiness(Posted 2004) [#6]
If you only need to load a single array of that size it doesn't matter much, virtually instant anyway. You could save it as 1-bit bitmap, and then presume that standard imageloading is done fast, but then you would have to convert the image to an array, if it's about speed. Well, don't bother if it's not a problem.


MSW(Posted 2004) [#7]
You don't need to use Chr$(0) and Chr$(255) to store it...Chr$(0) and Chr$(1) would work just fine...here is a way to write/load the array:

;savearray

Temp$="" ;clear the temp string

For x=0 to 319; or 1 to 320...whichever way you are doing it
For y=0 to 239; or 1 to 240...

 temp=temp + chr$(array(x,y))

Next 
Next

file = openfile("myfile.dat")
Writestring(file,temp)  ;writes the string all at once in binary forum
Closefile file



;to load the the array

Temp$="" ;clear the temp string

Openfile("myfile.dat")
Readstring file,temp
Closefile file

counter = 1

For x = 0 to 319 ; or 1 to 320
For y = 0 to 239 : or 1 to 240

 array(x,y) = Asc( Mid$( temp, counter, 1))

counter = counter + 1

Next
Next




also...if the array is nothing but bit values (1 and 0) why not save a whole hell of a lot of memory by useing the individual bits of an integer to store the values...so instead of useing 4 bytes (32-bits) to store a 0 or 1...use each of the 32 bits, then useing bitwise operations to test/set them? It's a little more complicated to set-up and use...but you can go from useing a 320 X 240 integer array of 32-bit integeres (approx 300k...while your chr$() basied storage method of one byte per bit value uses some 75k)...you can reduce this down to an integer array of 10 X 240 which is 9.4k?...then when checking if the bit is set...arrayindex% = testX / 32 : bitoffset% = testX MOD 32...and to check the bitvalue....check = (array(arrayindex, testY) shr bitoffset) AND 1