Highlighted

Is using ByteArray.writeObject() a good way to save state?

Contributor ,
Dec 11, 2018

Copy link to clipboard

Copied

Hi All,

I'm thinking of switching from using SharedObject for saving state to using ByteArray.writeObject() then saving the ByteArray instance as a file.

I found some code on the Starling forum that does this (see below). It looks fairly straightforward.

Have any of you tried this general approach and found it to be reliable?

Or, tried it and found out that there are "gotchas"?

I don't need to encrypt my data - just need to save and retrieve strings, numbers, and arrays of strings and numbers.

All feedback welcome 

Thanks,

Douglas

Sample code by "andtankian":

registerClassAlias("MyClass", MyClass);

var file:File; //To point to a file in local storage

var fs:FileStream; //To operate the stream action

var bytes:ByteArray; //Container to your serialized class

bytes = new ByteArray();

file = File.applicationStorageDirectory.resolvePath("the path you wanna save it");

bytes.writeObject(entity); //entity is the object class containing the data you wanna save (a MyClass object)

//don't forget you cannot save any subclasses which extend DisplayObject.

fs.open(file, FileMode.WRITE);

fs.writeBytes(bytes);

fs.close()

fs.open(file, FileMode.READ);

fs.readBytes(bytes);

entity = bytes.readObject() as MyClass;

fs.close();

TOPICS
Development

Views

379

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more

Is using ByteArray.writeObject() a good way to save state?

Contributor ,
Dec 11, 2018

Copy link to clipboard

Copied

Hi All,

I'm thinking of switching from using SharedObject for saving state to using ByteArray.writeObject() then saving the ByteArray instance as a file.

I found some code on the Starling forum that does this (see below). It looks fairly straightforward.

Have any of you tried this general approach and found it to be reliable?

Or, tried it and found out that there are "gotchas"?

I don't need to encrypt my data - just need to save and retrieve strings, numbers, and arrays of strings and numbers.

All feedback welcome 

Thanks,

Douglas

Sample code by "andtankian":

registerClassAlias("MyClass", MyClass);

var file:File; //To point to a file in local storage

var fs:FileStream; //To operate the stream action

var bytes:ByteArray; //Container to your serialized class

bytes = new ByteArray();

file = File.applicationStorageDirectory.resolvePath("the path you wanna save it");

bytes.writeObject(entity); //entity is the object class containing the data you wanna save (a MyClass object)

//don't forget you cannot save any subclasses which extend DisplayObject.

fs.open(file, FileMode.WRITE);

fs.writeBytes(bytes);

fs.close()

fs.open(file, FileMode.READ);

fs.readBytes(bytes);

entity = bytes.readObject() as MyClass;

fs.close();

TOPICS
Development

Views

380

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Dec 11, 2018 0
Advocate ,
Dec 12, 2018

Copy link to clipboard

Copied

Yeah I use it and it works fine. The bigger the object the slower it gets, it's also not suitable for displayobjects but for data it's fine. Due to file size I dropped this approach to simply saving data and restoring it (values) as string, int, float, etc ... This way the file is smaller and everything is faster. Doing it by values is trickier with bytearray (not that complicated though) but at the end you work with tiny file size and very fast parsing.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Dec 12, 2018 0
Contributor ,
Dec 12, 2018

Copy link to clipboard

Copied

Thanks ASWC 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Dec 12, 2018 1
Contributor ,
Dec 18, 2018

Copy link to clipboard

Copied

Hi All,

Here (below) is some code that I'm currently using for this. I originally posted this on another thread, but it's more appropriate to put it here.

I haven't tested it thoroughly yet, but it seems to work so far.

Also, in the other thread, ASWC offered some feedback. Here it is with my responses:

> This should work without problem as long as you are saving primitive values but here's the question,

> is saving only primitive values then why would you need a dictionary? If you need a dictionary then

> you might save complex values, if you save complex values then you are required to register their

> classes to be able to save/retrieve them. Are you saving complex objects and are you correctly

> using RegisterClassAlias?

Currently the only complex values that I'm using are Arrays, and they will only hold primitive values or other Arrays. I'm assuming that I don't need to register Array. But, as I said, I haven't fully tested this yet.

Are you suggesting that I could simply use Object, instead of Dictionary? If so, this makes sense. I'm not sure why I'm using Dictionary. 

Also, it would probably be a good idea to do some type-checking in setProperty() to enforce the limited types that this class is designed to support. This would help me to notice, years from now, if/when I start to save custom complex objects, and remind me that I need to use RegisterClassAlias.

Douglas

Here's the code I'm using ... I don't see any option in this forum's editor that will allow me to prevent formatting - indents etc. - from getting munged - so, sorry about the lousy formatting - and does anyone know how to insert code into these threads in a way that prevents this sad munging?

public class ByteArrayPersistenceManager {

   private var _initialized:Boolean;

   private var _persistenceDict:Dictionary;

   // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  //
  // Public Methods
  //
  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

   public function ByteArrayPersistenceManager() {

   initializeIfNeeded();

  }

   public function setProperty(key:String, value:Object):void {

   initializeIfNeeded();

   if (_persistenceDict != null)

   _persistenceDict[key] = value;

  }

   public function getProperty(key:String):Object {

   initializeIfNeeded();

   if (_persistenceDict != null) {

   if (_persistenceDict.hasOwnProperty(key)) {

   return _persistenceDict[key];

  }

   else {

   return null;

  }

  }

   else {

   return null;

  }

  }

   public function save():Boolean {

   if (_initialized) {

   try {

   var fs:FileStream = new FileStream();

   var file:File = File.applicationStorageDirectory.resolvePath(getFilePath());

   fs.open(file, FileMode.WRITE);

   var byteArray:ByteArray = new ByteArray();

   byteArray.writeObject(_persistenceDict);

   fs.writeBytes(byteArray);

   fs.close()

  }

   catch (e:Error) {

  Log.error("ByteArrayPersistenceManager.save() - save failed: " + e.message);

   return false;

  }

   return true;

  }

   else {

  Log.error("ByteArrayPersistenceManager.save() - instance not initialized");

   return false;

  }

  }

   // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  //
  // Private Methods
  //
  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

   private function initializeIfNeeded():void {

   if (!_initialized)

   load();

  }

   private function getFilePath():String {

   var result:String = Constant.FILEPATHINFO__PERSISTENCE_FOLDER_NAME + File.separator + Constant.FILEPATHINFO__PERSISTENCE_FILE_FILE_NAME;

   return result;

  }

   private function load():Boolean {

   try {

   var file:File = File.applicationStorageDirectory.resolvePath(getFilePath());

   if (file.exists) {

   var fs:FileStream = new FileStream();

   fs.open(file, FileMode.READ);

   var byteArray:ByteArray = new ByteArray();

   fs.readBytes(byteArray);

   fs.close();

   _persistenceDict = Dictionary(byteArray.readObject());

  }

   else {

   _persistenceDict = new PersistenceDict();

  }

   _initialized = true;

  }

   catch (e:Error) {

  Log.error("ByteArrayPersistenceManager.load() - load failed: " + e.message);

  }

   return _initialized;

  }

}

}

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Dec 18, 2018 0