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:

B4X:
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
 

stevel05

Expert
Licensed User
Longtime User
Does it compile with this line?

B4X:
 signature = levelRAF.readObject(signature,levelRAF.CurrentPosition)

the Documentation has

B4X:
ReadObject(Position As Long) As Object
 
Upvote 0

sterlingy

Active Member
Licensed User
Longtime User
the Documentation has

B4X:
ReadObject(Position As Long) As Object
Steve,

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

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

-Sterling
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
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

sterlingy

Active Member
Licensed User
Longtime User
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

stevel05

Expert
Licensed User
Longtime User
what code did you use to write the file?
 
Upvote 0

sterlingy

Active Member
Licensed User
Longtime User
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

stevel05

Expert
Licensed User
Longtime User
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:

B4X:
   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:

B4X:
   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

sterlingy

Active Member
Licensed User
Longtime User
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

stevel05

Expert
Licensed User
Longtime User
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

stevel05

Expert
Licensed User
Longtime User
One other thing to try is to set the Endianess to LittleEndian if it's not coming from Android it could well be mismatched:

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

Got the same OOM error with a mismatch.
 
Last edited:
Upvote 0

sterlingy

Active Member
Licensed User
Longtime User
B4X:
levelRAF.Initialize2(File.DirRootExternal, "/Scooper/level.level", False,True)


I tried Initialize2 and got the same error

-Sterling
 
Last edited:
Upvote 0

stevel05

Expert
Licensed User
Longtime User
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

thedesolatesoul

Expert
Licensed User
Longtime User
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

sterlingy

Active Member
Licensed User
Longtime User
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
Cookies are required to use this site. You must accept them to continue using the site. Learn more…