B4J Question Saving custom type objects to file splits incorrectly when loaded

kostefar

Active Member
Licensed User
Longtime User
Dear All,

First, I know that b4xobject probably would be the way to go for this task. The reason for using the standard textreader is that I like the files to be human readable afterwards.

Ok, here we go...

I am building a list of objects while the app is running, and when new objects arrived, they all get saved (again) to a file. The object is custom, and looks like this:

B4X:
Type custommsg (cbq As String, username As String, msg As String, msgdate As String, userid As String, msgid As String)

And here´s how they´re written:

B4X:
TxWr.WriteList(messagelist.Items)

I don´t recall why I didn´t add them as they arrive instead of as the whole list, but I think it´s got to do with that they´re sorted in a particular way before written.

When the app is loaded, then list is loaded again in the following way:

B4X:
If File.Exists("","NxtGenMsg.txt") Then
    Dim TxRd As TextReader
        TxRd.Initialize(File.OpenInput("","NxtGenMsg.txt"))
        messagelist.Items.AddAll(TxRd.ReadList)
       
        TxRd.close

But this is what happens when running through the list afterwards with:

B4X:
For i = 0 To messagelist.Items.Size - 1
   
    Log ("test for break " & messagelist.Items.Get(i))
Next

B4X:
test for break [IsInitialized=false, cbq=(CallbackQuery) Not initialized, username=n0ll
test for break , msg=/start, msgdate=1530140844, userid=32
test for break , msgid=200]

You will see that it says "n0ll" instead of null. That´s because I had a suspicion that when a null occurs, there´s a line break added so I called a sub which would look for null, and replace it with n0ll. This unfortunately did not solve the problem.

Obviously, the desired way of loading would be that everything between the brackets is loaded into one line, but that´s not happening.

Is there a workaround for this, other than saving the items with some unique separator "8792QFQEEFF" or whatever never would occur, then load the file as one and use a regex.split afterwards?
Not even sure if the items would be handled as the custom type that way, as they´re now becoming strings.

I hope somebody can help with this!

PS: I just went to asciivalue.com and found out what it looks like if I paste from the text file directly:

n 110 6E 156
0 48 30 60
l 108 6C 154
l 108 6C 154
13 0D 15
10 0A 12

Oops, there´s a line break there. But where did that come from?
 

OliverA

Expert
Licensed User
Longtime User
As per https://www.b4x.com/b4j/help/files.html#textwriter_writelist
All values will be converted to strings.
So your custom type will be converted to a string.
As per https://www.b4x.com/b4j/help/files.html#textreader_readlist
Reads the remaining text and returns a List object filled with the lines.
So now your reading pure text, without knowledge of a custom type. ReadList will not recreate the custom type for you.

You would need to write a sub that takes your custom type and extracts the information in a manner that allows you to write it out to a plain text file via WriteList. You would then need to write another sub that uses ReadList to read your items and then place them back into your custom type. This is just one option.
 
Upvote 0

kostefar

Active Member
Licensed User
Longtime User
As per https://www.b4x.com/b4j/help/files.html#textwriter_writelist

So your custom type will be converted to a string.
As per https://www.b4x.com/b4j/help/files.html#textreader_readlist

So now your reading pure text, without knowledge of a custom type. ReadList will not recreate the custom type for you.

You would need to write a sub that takes your custom type and extracts the information in a manner that allows you to write it out to a plain text file via WriteList. You would then need to write another sub that uses ReadList to read your items and then place them back into your custom type. This is just one option.

Thanks OliverA,

Shouldn´t be too hard - basically the same logic as behind the regex trick I mentioned, but smarter because it still maintains that it´s a list rather than having to split it when loading.
 
Upvote 0
Top