Android Question I Populate a Random Access File With 2 Lists, But Only One Is Displayed

Mahares

Expert
Licensed User
Longtime User
1. I add list L1 to raf
2. I append list L2 to raf.
3. I read list L3 as the entire raf file, but L2 data is not shown in L3 when raf is read. Any thoughts?
Thank you
I am simply testing the power of RAF a little further, using RAF 2.20. Here is the complete project:
B4X:
Sub Activity_Create(FirstTime As Boolean)
   
    If File.Exists(File.DirRootExternal, "myraffile") Then
        File.Delete(File.DirRootExternal, "myraffile")
    End If
    raf.Initialize(File.DirRootExternal, "myraffile", False)

    Dim L1 As List
    L1.Initialize
   
    Dim MyMap As Map
    MyMap.Initialize
    MyMap.Put("City", "AA")
    MyMap.Put("Country", "Prime Country")
    MyMap.Put("Continent", "America")
    MyMap.Put("Tourism", "Good")
    L1.Add(MyMap)
   
    Dim MyMap As Map
    MyMap.Initialize
    MyMap.Put("City", "EE")
    MyMap.Put("Country", "Second Country")
    MyMap.Put("Continent", "Europe")
    MyMap.Put("Tourism", "Great")
    L1.Add(MyMap)

    Dim MyMap As Map
    MyMap.Initialize
    MyMap.Put("City", "FF")
    MyMap.Put("Country", "Third Country")
    MyMap.Put("Continent", "Africa")
    MyMap.Put("Tourism", "Very good")
    L1.Add(MyMap)
   
    raf.WriteB4XObject(L1, 0)
    Log("Size after L1: " & raf.Size)
   
    Dim L2 As List
    L2.Initialize
    Dim MyMap As Map
    MyMap.Initialize
    MyMap.Put("City", "II")
    MyMap.Put("Country", "Fourth Country")
    MyMap.Put("Continent", "Australia")
    MyMap.Put("Tourism", "Terrific")
    L2.Add(MyMap)

    raf.WriteB4XObject(L2,raf.CurrentPosition)
    Log("Size after L2: " & raf.Size)
   
    Dim L3 As List
    L3.Initialize   
    L3=raf.ReadB4XObject(0)  'read to a new list L3
    Log("size: " & L3.Size & ".   " & L3 )

    For x = 0 To L3.Size - 1
        Dim MyMap As Map       
        MyMap = L3.Get(x) 
        For Each k As Object  In MyMap.keys
            Log(k &  "    "  & MyMap.Get(k)  )
        Next
        Log("-------")
    Next
    raf.Close
End Sub[code]
 

KMatle

Expert
Licensed User
Longtime User
Upvote 0

Mahares

Expert
Licensed User
Longtime User
Easier: Just write ONE list.
I did test it with ONE list prior to posting and it works fine. I would like to challenge the capability of RAF. This is just a test to play with. I do not have a real project. Maybe, @Erel and company can figure out where I went astray.
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
you can store multiple lists into one raf-file...
just make sure you know which item of the file you want to write/read.

B4X:
raf.WriteB4XObject(L1, 0) ' will write a new file and it´s 1. item will be the list.

raf.WriteB4XObject(L2, 1) ' will write another list to this file.

Make sure to know which list you want to read.
B4X:
dim l1 as list = raf.ReadB4XObject(0)
dim l2 as list = raf.ReadB4XObject(1)
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
you can store multiple lists into one raf-file...
just make sure you know which item of the file you want to write/read.
Here is the new code based on @DonManfred's suggestion, but returns the error:
L3=raf.ReadB4XObject(0) 'read to a new list L3
java.io.EOFException
B4X:
Sub Activity_Create(FirstTime As Boolean)
   
    If File.Exists(File.DirRootExternal, "myraffile") Then
        File.Delete(File.DirRootExternal, "myraffile")
    End If
    raf.Initialize(File.DirRootExternal, "myraffile", False)

    Dim L1 As List
    L1.Initialize
   
    Dim MyMap As Map
    MyMap.Initialize
    MyMap.Put("City", "AA")
    MyMap.Put("Country", "Prime Country")
    MyMap.Put("Continent", "America")
    MyMap.Put("Tourism", "Good")
    L1.Add(MyMap)
   
    Dim MyMap As Map
    MyMap.Initialize
    MyMap.Put("City", "EE")
    MyMap.Put("Country", "Second Country")
    MyMap.Put("Continent", "Europe")
    MyMap.Put("Tourism", "Great")
    L1.Add(MyMap)

    Dim MyMap As Map
    MyMap.Initialize
    MyMap.Put("City", "FF")
    MyMap.Put("Country", "Third Country")
    MyMap.Put("Continent", "Africa")
    MyMap.Put("Tourism", "Very good")
    L1.Add(MyMap)
   
    raf.WriteB4XObject(L1, 0)
    Log("Size after L1: " & raf.Size)
   
    Dim L2 As List
    L2.Initialize
    Dim MyMap As Map
    MyMap.Initialize
    MyMap.Put("City", "II")
    MyMap.Put("Country", "Fourth Country")
    MyMap.Put("Continent", "Australia")
    MyMap.Put("Tourism", "Terrific")
    L2.Add(MyMap)
    raf.WriteB4XObject(L2,1)
    Log("Size after L2: " & raf.Size)
   
    Dim L3 As List
    L3.Initialize   
    L3=raf.ReadB4XObject(0)  'ERROR HERE
    Log("size: " & L3.Size & ".   " & L3 )

    For x = 0 To L3.Size - 1
        Dim MyMap As Map       
        MyMap = L3.Get(x) 
        For Each k As Object  In MyMap.keys
            Log(k &  "    "  & MyMap.Get(k)  )
        Next
        Log("-------")
    Next
    raf.Close
End Sub
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Try this
B4X:
Dim L1 As List
    L1.Initialize
  
    Dim MyMap As Map
    MyMap.Initialize
    MyMap.Put("City", "AA")
    MyMap.Put("Country", "Prime Country")
    MyMap.Put("Continent", "America")
    MyMap.Put("Tourism", "Good")
    L1.Add(MyMap)
  
    Dim MyMap As Map
    MyMap.Initialize
    MyMap.Put("City", "EE")
    MyMap.Put("Country", "Second Country")
    MyMap.Put("Continent", "Europe")
    MyMap.Put("Tourism", "Great")
    L1.Add(MyMap)

    Dim MyMap As Map
    MyMap.Initialize
    MyMap.Put("City", "FF")
    MyMap.Put("Country", "Third Country")
    MyMap.Put("Continent", "Africa")
    MyMap.Put("Tourism", "Very good")
    L1.Add(MyMap)
  
    RAF.WriteB4XObject(L1, 0)
    Log("Size after L1: " & RAF.Size)
    RAF.CurrentPosition = RAF.Size
  
    Dim L2 As List
    L2.Initialize
    Dim MyMap As Map
    MyMap.Initialize
    MyMap.Put("City", "II")
    MyMap.Put("Country", "Fourth Country")
    MyMap.Put("Continent", "Australia")
    MyMap.Put("Tourism", "Terrific")
    L2.Add(MyMap)
    RAF.WriteB4XObject(L2,RAF.Size)
    Log("Size after L2: " & RAF.Size)
    RAF.CurrentPosition = 0
  
    Dim L3 As List
    L3.Initialize
    L3=RAF.ReadB4XObject(0)  'ERROR HERE
    Log("size: " & L3.Size & ".   " & L3 )

    For x = 0 To L3.Size - 1
        Dim MyMap As Map
        MyMap = L3.Get(x)
        For Each k As Object  In MyMap.keys
            Log(k &  "    "  & MyMap.Get(k)  )
        Next
        Log("-------")
    Next
    RAF.Close

You are writing L2 at position 1 which will corrupt the stored version of L1 by overwritin all but the data in position 0. The position needs to be set to the end of the previous record.
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
Thanks @stevel05 . That takes care of that problem. However, my original post objective was to add L1 to raf file, then append L2 to raf file. I was hoping I can generate a new list L3 which is composed of L1 and L2 by reading the raf file, not one list or the other. If that is possible, that is great.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
This should do it:
B4X:
Dim L3 As List
    L3.Initialize
    L3=RAF.ReadB4XObject(0)  'ERROR HERE
    L3.AddAll(RAF.ReadB4XObject(RAF.CurrentPosition))
    Log("size: " & L3.Size & ".   " & L3 )

    For x = 0 To L3.Size - 1
        Dim MyMap As Map
        MyMap = L3.Get(x)
        For Each k As Object  In MyMap.keys
            Log(k &  "    "  & MyMap.Get(k)  )
        Next
        Log("-------")
    Next

As the current position is set once the first object is read, it is already positioned to read the next one. Using L3.AddAll will append the contents of the stored list to list3.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
If you want to jump around within the file and read different objects, you will need to keep an index of their positions, or read them all sequentially until you get to the one you want, although that defeats the object of using a RandomAccess File.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Just a further thought, if it's a one hit creation then it should work OK. If you are going to change any of the data and save it again then maintaining the indexes would be problematic, it would be better to use a SQL database.
 
Upvote 0
Top