RAF reading problem

sterlingy

Active Member
Licensed User
Longtime User
I'm trying to read from a file. The first object is a string, but when I try to read it, I get an Out of Memory error:

Code: Copy
Dim levelRAF As RandomAccessFile
   Dim signature As String
   If File.Exists(File.DirRootExternal, "/Scooper/level.level") Then
      levelRAF.Initialize(File.DirRootExternal, "/Scooper/level.level", False)
      signature = levelRAF.readObject(signature,levelRAF.CurrentPosition)
      Log("Signature: " & signature)
   Else
      Log("No File")
   End If

If, on the other hand, I read the file with readBytes, it works, but then I have to rebuild my objects, so this isn't very efficient.

Thoughts anyone?

-Sterling
 
Does it compile with this line?

Code: Copy
 signature = levelRAF.readObject(signature,levelRAF.CurrentPosition)

the Documentation has

Code: Copy
ReadObject(Position As Long) As Object
 
Upvote 0
the Documentation has

Code: Copy
ReadObject(Position As Long) As Object
Steve,

My bad. I put the wrong code in here. the line is actually:
Code: Copy
signature = levelRAF.readObject(levelRAF.CurrentPosition)

And it does compile and I get the Out Of Memory Error

-Sterling
 
Upvote 0
Well then it has to be either a problem with the written file, or something different altogether. Can you post the error from the log?
 
Upvote 0
Here's what I get:

main_activity_create (B4A line: 323)
signature = levelRAF.readObject(levelRAF.CurrentPosition)
java.lang.OutOfMemoryError
at anywheresoftware.b4a.randomaccessfile.RandomAccessFile.readHelper(RandomAccessFile.java:375)
at anywheresoftware.b4a.randomaccessfile.RandomAccessFile.ReadObject(RandomAccessFile.java:362)
at scooper.game.main._activity_create(main.java:937)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:167)
at scooper.game.main.afterFirstLayout(main.java:89)
at scooper.game.main.access$100(main.java:16)
at scooper.game.main$WaitForLayout.run(main.java:74)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
** Activity (main) Resume **
 
Upvote 0
Someone else wrote that code. It's a third party program that wasn't written in B4A.

I'll have him take a look at it.

Essentially, you are suggesting that the B4A code to read the String should be working?

-Sterling
 
Upvote 0
It works in a small test I've done, using WriteObject and ReadObject, but if I use WriteBytes and ReadObject I get an out of memory error.

That's the next thing to check.

Code that fails:

Code: Copy
   Dim BC As ByteConverter
   Dim levelRAF As RandomAccessFile
   levelRAF.Initialize(File.DirRootExternal, "level.level", False)
   Dim B() As Byte = BC.StringToBytes("Test","UTF-8")
   Log(B.Length)
   levelRAF.WriteBytes(B,0,4,0)
   levelRAF.Flush
   levelRAF.Close
   
   Log("Here...")
    Dim signature As String
    If File.Exists(File.DirRootExternal, "level.level") Then
        levelRAF.Initialize(File.DirRootExternal, "level.level", False)
        signature = levelRAF.readObject(levelRAF.CurrentPosition)
        Log("Signature: " & signature)
    Else
        Log("No File")
    End If

Code that works:

Code: Copy
   Dim levelRAF As RandomAccessFile
   levelRAF.Initialize(File.DirRootExternal, "level.level", False)
   levelRAF.WriteObject("Test",False,0)
   levelRAF.Flush
   levelRAF.Close
   
   Log("Here...")
    Dim signature As String
    If File.Exists(File.DirRootExternal, "level.level") Then
        levelRAF.Initialize(File.DirRootExternal, "level.level", False)
        signature = levelRAF.readObject(levelRAF.CurrentPosition)
        Log("Signature: " & signature)
    Else
        Log("No File")
    End If
 
Last edited:
Upvote 0
I have a sneaky suspicion that the language he used to create the file, does not have writeObject, but it has writeString, and that my not be compatible with B4A readObject, but explains why readByte did work.

-Sterling
 
Upvote 0
I don't know the technicalities behind it, but it sounds plausible. You may have to work round this one. Someone else may have a solution.
 
Upvote 0
One other thing to try is to set the Endianess to LittleEndian if it's not coming from Android it could well be mismatched:

Code: Copy
levelRAF.Initialize2(File.DirRootExternal, "/Scooper/level.level", False,True)

Got the same OOM error with a mismatch.
 
Last edited:
Upvote 0
OK, that's the extent of my knowledge then on that I'm afraid. Hopefully someone else can give you some more information.
 
Upvote 0
ReadObject will only work with WriteObject.
You cannot use another external program to write it.
Use ReadString if it is just a string.
I think WriteObject internally serializes the type and also compresses the data.
I switched to manually writing my objects (serializing them myself) due to some problems.
 
Upvote 0
The problem is that this reads the entire file into a string, and I don't want to do that. There are many different TYPEs in the file, so it's looking like I'll have to parse it with RAF using GetBytes or parse it after I load the file into a String.

-Sterling
 
Upvote 0
Back
Top