B4A Library RandomAccessFile - V1.10 - Read/Write objects

Status
Not open for further replies.
This is a beta version of an important new feature.

Two new methods were added to RandomAccessFile: WriteObject and ReadObject.
These methods allow you to write and read objects to files easily.
The following types of objects are supported: lists, maps, arrays, strings, primitive types (numeric types) and user defined types.
Combinations of these types are also supported.

Unlike File.ReadMap or ReadList which convert the data to string, here the data type is kept. This means that the file is not a text file. It is a binary file.

Another new field was added named CurrentPosition. This field holds the current file position. It advances automatically after each read or write.
For example, writing an array to a file:
B4X:
    Dim raf As RandomAccessFile
    raf.Initialize(File.DirRootExternal, "1.dat", False)
    Dim arr(10) As Int
    'fill the array...
    raf.WriteObject(arr, True, raf.CurrentPosition)
    raf.Close
Installation instructions:
- Unzip the attached file.
- Copy both files to the internal libraries folder: C:\Program Files\Anywhere Software\Basic4android\Libraries
 

Attachments

  • RandomAccessFile.zip
    16 KB · Views: 1,192

davide69

Member
Licensed User
Hello Erel,

Thanks for the updated library! :sign0087:

I am not sure how to use it, could you please take a look on my save sub:

Dim raf As RandomAccessFile
Dim array1(100) as int
Dim array2(100) as int

''fill array
raf.Initialize(File.DirRootExternal, "1.dat", False)
raf.WriteObject(array1, True,0)
raf.WriteObject(array2, True,1)
raf.Close

Position 0 an 1 are correct or should i care about the size of the array?
What is the sintax to read the two arrays just saved? Perhaps something like this:

raf.Initialize(File.DirRootExternal, "1.dat", False)
array1=raf.readObject(0)
array2=raf.readObject(1)
raf.Close


Thanks for your help

Davide
 

Erel

Administrator
Staff member
Licensed User
RandomAccessFile is byte oriented. The position specified is the offset from the file beginning in bytes.
You should use CurrentPosition:
B4X:
raf.WriteObject(array1, True,raf.CurrentPosition)
raf.WriteObject(array2, True,raf.CurrentPosition)
B4X:
raf.Initialize(File.DirRootExternal, "1.dat", False) 'CurrentPosition=0 after initialize
array1=raf.readObject(raf.CurrentPosition)
array2=raf.readObject(raf.CurrentPosition)
 

thedesolatesoul

Expert
Licensed User
I have a question regarding ReadObject.
If I do not know how many objects were stored in the file and I need to loop through them, how do I do it.

This doesnt work:
B4X:
Dim pipe1 As PipeType 
Dim f As RandomAccessFile 
db.DropPipes.Initialize 
If File.Exists(File.DirInternal,"PipeData") Then
   f.Initialize(File.DirInternal,"PipeData",True)
   Do While (f.CurrentPosition < f.Size )
      pipe1 = f.ReadObject(f.CurrentPosition)
      DB.DropPipes.Add(pipe1)
   Loop
   f.Close 
End If

I know I can assign the whole list at once probably. But I also want to know how to go through the file and add selected objects.
Thanks.
 

Erel

Administrator
Staff member
Licensed User
The problem is with the writing code. Each object is written over the previous one:
B4X:
   For i = 0 To PipeList.Size -1
      f.WriteObject(PipeList.Get(i),False,i)
   Next
The first object starts from byte 0, the second object starts from byte 1 and so on.
The code should be:
B4X:
   For i = 0 To PipeList.Size -1
      f.WriteObject(PipeList.Get(i),False,f.CurrentPosition)
   Next
I recommend you to set compression to true. It will make the file much smaller.
 

philfred

Member
Licensed User
writing out the contents of Scrollview

Hi Erel,
I have a scrollview that will contain both text labels
and also labels with bitmaps.
I addviews of label
or a listview to get the label with a bitmap (that might not be the solution?)

I want to be able to then save the contents of all of this and reload it later...

The project is to help my autistic son, he uses a schedule of his day which is basically a to do list with pictures and words... I tried using your statemanager to do some of the saving for me but it works with the labels but wont save the list view...

Using the objects is there a way to get the contents and save the information?

Or am I over complicating things?

Many thanks
Phil
 

philfred

Member
Licensed User
What do you want to save? The text and the bitmap of each item (or maybe the image file name) ?

Thanks for the reply :)

Ideally all of the above...

A typical schedule might have

Breakfast
Get Dressed
Laptop
Car
Cinema -< Picture of cinema
Home

etc..

But there could be a picture on any of these and on some days the schedule would be an exact repeat - so being able to load its contents is the goal as well as saving it....

Currently i am looking at choosing pictures from the gallery on the phone using the chooser which works and then placing them on the listview but dont think this is the best way as the pictures are way too small.

Thanks for your help this sort of fustrates me a little :BangHead: as I am programmer in delphi and php and I have to ask :sign0104: questions :)

Thanks for the response
Phil
 

mjtaryan

Active Member
Licensed User
Is it possible to use something like the following as ReadObject and WriteObject within the RAF library? See psuedo code below (the leading periods represent indentation):

MedLib as Record 'User-defined type
.....MedName as String 'Medication name.
.....MedPurp as Int 'Purpose type of Medication.
.....MedDoze as Int 'Daily dosage.
.....LastRefill as Date 'Date last refilled.
End Record

In other words, does B4A have a pre-defined Record type from which a record can be declared and then written/read as an object to an raf? If so, how will the file position be updated/modified?
 
Last edited:

KY Leng

Member
Licensed User
What happen if one service is writing the file using WriteObject and other service is trying to write or read the same file at the same time?
 
Status
Not open for further replies.
Top