خواندن و نوشتن اشیاء اختصاصی در AS3 و عمل Serialization

یکی از مفاهیم بسیار مهم در جا‌به جایی اطلاعات، مبحث Serialization است که در مورد چگونگی قرارگیری داده‌ها در امتداد یکدیگر به منظور خواندن و نوشتن می‌پردازد.

flash as3

به عنوان مثال:
– ذخیره کردن یک کلاس در Shared Object
– خواندن و نوشتن اشیاء در ByteArray
– خواندن و نوشتن داده‌ها در فایل‌ها
– ارسال اطلاعات از طریق تکنولوژی‌هایی مانند AMF

موارد فوق همگی از حالاتی هستند که از مفهوم Serialization استفاده می‌گردد.

در زمان کار با داده‌های استانداردی مانند int، uint، String، Date، Array و …، AS3 می‌داند که اطلاعات ذخیره شده در این اشیاء را چگونه ذخیره و بازیابی نماید. اما اگر شئ مورد نظر از یک کلاس اختصاصی و غیر استاندارد ایجاد شده باشد، تعیین ترتیب خوانده و نوشته شدن محتوای آن شئ به عهده برنامه نویس خواهد بود.

به عنوان مثال در حالت زیر، استفاده از انواع داده‌ای استاندارد بدون هیچ مشکلی انجام خواهد شد:

var n:int = 55;
var s:String = "mshams.ir";
var dn:Number = 122333444455555;
var b:Boolean = false;
var o:Object = {"name": "year", "val": new Date().fullYear};

var ba:ByteArray = new ByteArray();
ba.writeInt(n);
ba.writeUTF(s);
ba.writeDouble(dn);
ba.writeBoolean(b);
ba.writeObject(o);

ba.position = 0;

trace("ByteArray size:", ba.length);
trace(ba.readInt());
trace(ba.readUTF());
trace(ba.readDouble());
trace(ba.readBoolean());
trace(ba.readObject().val);

/*OUTPUT:
ByteArray size: 24
55
mshams.ir
122333444455555
false
2014
*/

همانطور که می‌بینید، به همان ترتیبی که اشیاء نوشته شده‌اند، خوانده نیز خواهند شد. اما اگر از یک کلاس اختصاصی مانند مثال زیر استفاده شده باشد، عمل خواندن با خطا روبرو می‌شود:

class Person  {
     var name:String;
     var age:uint;	
}

دلیل بروز خطا این است که AS3 اطلاعی از چگونگی رفتار با محتوای این کلاس ندارد.

برای حل این مشکل باید فرآیند Serialization در کلاس مذکور پیاده سازی شود. به این منظور ، کلاس Person ابتدا باید نسبت به پیاده‌سازی اینترفیس IExternalizable اقدام کند.
سپس دو تابع readExternal و writeExternal در آن تعریف شده و ترتیب خواندن و نوشتن اطلاعات را مشخص نمایند. در نهایت می‌بایست با استفاده از دستور registerClassAlias، نوع داده‌ای Person را معرفی نماییم.

به عنوان مثال:

package {
	import flash.display.MovieClip;
	import flash.utils.ByteArray;
	import flash.net.registerClassAlias;
	import flash.utils.getQualifiedClassName;

	public class mainclass extends MovieClip {

		public function mainclass() {
			SimpleSerial();
			ComplexSerial();
		}

		private function SimpleSerial():void{
			var n:int = 55;
			var s:String = "mshams.ir";
			var dn:Number = 122333444455555;
			var b:Boolean = false;
			var o:Object = {"name": "year", "val": new Date().fullYear};

			var ba:ByteArray = new ByteArray();
			ba.writeInt(n);
			ba.writeUTF(s);
			ba.writeDouble(dn);
			ba.writeBoolean(b);
			ba.writeObject(o);

			ba.position = 0;

			trace("ByteArray size:", ba.length);
			trace(ba.readInt());
			trace(ba.readUTF());
			trace(ba.readDouble());
			trace(ba.readBoolean());
			trace(ba.readObject().val);

			/*OUTPUT:
			ByteArray size: 24
			55
			mshams.ir
			122333444455555
			false
			2014
			*/
		}

		private function ComplexSerial():void{			
			var p:Person = new Person();
			p.name = "john";
			p.age = 18;

			registerClassAlias("Person", Person);

			var ba:ByteArray = new ByteArray();
			ba.writeObject(p);
			ba.position = 0;

			trace("ByteArray size:", ba.length);

			var o:Object = ba.readObject();

			trace(getQualifiedClassName(o));
			trace((o as Person).age);

			/*OUTPUT:
			ByteArray size: 21
			::Person
			18
			*/
		}		

	}
}

import flash.utils.IDataInput;
import flash.utils.IDataOutput;
import flash.utils.IExternalizable;

internal class Person  implements IExternalizable{
	var name:String;
	var age:uint;	

	public function writeExternal(output:IDataOutput):void {
			output.writeUTF(name);
			output.writeUnsignedInt(age);
		}

	public function readExternal(input:IDataInput):void {
			name = input.readUTF();
			age = input.readUnsignedInt();
	}
}

این کار بدون هیچ خطایی انجام خواهد شد. حتی اگر از کلاس‌های اختصاصی به صورت ترکیبی یا در اشیاء آرایه‌ای استفاده شده باشد، به همین ترتیب می‌توان عمل نمود.
مثال:

package {
	import flash.display.MovieClip;
	import flash.utils.ByteArray;
	import flash.net.registerClassAlias;
	import flash.utils.getQualifiedClassName;

	public class mainclass extends MovieClip {

		public function mainclass() {
			ComplexVectorSerial();
		}

		private function ComplexVectorSerial():void{								
			var v:Vector .<Person> = new Vector.<Person>();

			v.push(new Person());
			v[0].name = "alpha"
			v[0].age = 18;

			v.push(new Person());
			v[1].name = "beta"
			v[1].age = 20;

			registerClassAlias("Person", Person);

			var ba:ByteArray = new ByteArray();
			ba.writeObject(v);
			ba.position = 0;

			trace("ByteArray size:", ba.length);

			var o:Object = ba.readObject();

			trace(getQualifiedClassName(o));
			trace(o[0].age, o[1].name);

			/*OUTPUT:
			ByteArray size: 38
			__AS3__.vec::Vector.<::Person>
			18 beta
			*/
		}

	}
}

import flash.utils.IDataInput;
import flash.utils.IDataOutput;
import flash.utils.IExternalizable;

internal class Person  implements IExternalizable{
	var name:String;
	var age:uint;	

	public function writeExternal(output:IDataOutput):void {
			output.writeUTF(name);
			output.writeUnsignedInt(age);
		}

	public function readExternal(input:IDataInput):void {
			name = input.readUTF();
			age = input.readUnsignedInt();
	}
}

About محمد شمس

برنامه‌نویس، طراح انیمیشن و علاقمند به هوش مصنوعی

One Comment

  1. سلام
    خوشحالم می شوم وقتی در مورد اکشن اسکریپت مطلبی فارسی می بینم.

    موفق و پیروز باشید

پاسخ دهید