How to make an object network serialize to a file, not a SharedObject?
Asked Answered
A

1

0

Currently, I do serialize my model object to the SharedObject instance:

 try {

     var mySo:SharedObject = SharedObject.getLocal("sig");

     mySo.clear();
     mySo.data.model = _model;
     mySo.flush();

  } catch ( e:Error ) {

    Alert.show( 'Leider konnte kein Modell geladen werden.' );

  }

Likewise, I load the saved model using the SharedObject instance. Works great.

Ultimately, I'd like to serialize it to a file - which fails. Here is how:

 var fp: File = File.applicationStorageDirectory;

 fp = fp.resolvePath( PREFS_FILENAME );

 var    _prefsStream:FileStream;
 _prefsStream = new FileStream();
 _prefsStream.open( fp, FileMode.WRITE );
 _prefsStream.endian = Endian.BIG_ENDIAN;

_model.writeExternal( _prefsStream );
_prefsStream.close();

The complementing read operation suddenly breaks and reports missing bytes.

In fact, I can't image how FileStream / _model.writeExternal() is able to serialize, since it needs to somehow know, that a new serialization operation is about to start. If it doesn't know, it won't be able to determine, which object instances are left to serialize.

Thus, I image that my concept is completely wrong or I missed how to initialize the serialization operation.

Please explains, what I'm missing.

I'd be happy to read the raw ByteArray from the shared object and write it to a file. Unfortunately, I didn't find a method to retrieve from a SharedObject a ByteArray of a certain property, in my case mySo.data.model. My question is loosely related to this one: Why does delete( DictionaryInstance[ key ] ); fail?

Anion answered 10/10, 2011 at 20:33 Comment(0)
F
1

I once had to perform unit tests on an externalization framework I built and this is how I did it:

byteArray.writeObject(myObject);
byteArray.position = 0;
readValue = byteArray.readObject();

Also, I don't think you should have to worry about byte order, I think the default is big endian anyways.

So, for your case, I think you need something like:

fileStream.writeObject(myObject)

as opposed to:

myObject.writeExternal(_prefsStream);

The runtime should call writeExternal on your model automagically.

Futurism answered 10/10, 2011 at 20:48 Comment(7)
Regarding the byte order: Wanted to make sure that the code is cross-platform. Just to make sure ;-) Ah, writeObject() might be the essential point! Let's see. Will come back...Anion
Thank you very much! Great hint! OK, writeObject() seems to prepare/maintain the list of already serialized object instances and all the magical rest. Still: How does writeObject() know, that a fresh serialization operation just started? I mean, how does it know, that it needs to save all reachable object instances?Anion
It crawls the object tree. For example, every call to writeObject does a test to see if the object implements IDataOutput or IExternalizable. If so, it calls writeExternal on the object to give it a chance to serialize itself. If not, it tries to serialize it as best as it can (using public properties etc.) or if it's a simple object (ie String, Number, Object, Array, etc) it simply calls into those methods to serialize it. I've served my time fighting with IExternalizable, but once you get the hang of it, you can do pretty cool stuff.Futurism
Also, so if a custom class serializes another custom class, it just repeats and keeps crawling the tree until the entire tree is serialized.Futurism
But suppose I call writeExternal later on again. The runtime somehow needs to know, that a fresh serialization operation is about to start. Doesn't it?Anion
Why would you manually call writeExternal? The runtime calls that for you when you call writeObject.Futurism
Type. Rule of thumb: To serialize, implement the methods writeExternal() and readExternal(): Inside these routines and which writing to or reading from a serialization destination/source, always use writeObject() and readObject().Anion

© 2022 - 2024 — McMap. All rights reserved.