AS3对象序列化存储

AS3对象序列化存储

23.6.1.问题
我想对自定义对象进行序列化并保存到硬盘驱动器的文件中。
23.6.2.解决办法
通过class-alias注册自定义类,使用ActionScript Message Format (AMF) 编码序列化对象,并使用FileStream.writeObject方法把对象存储到文件上。
23.6.3.讨论
使用AIR文件系统API,你可以把经过AMF编码序列化过的对象写入文件流缓冲区中。

ActionScript语言中大多数内建对象类型比如String和Boolean都自动支持序列化。这些类型同通过AMF被编码为二进制格式,当经过反序列化可以恢复原来的值。然而自定义对象是不自动支持序列化的,要启动自定义对象序列化支持,你需要用registerClassAlias 方法用一个类别名注册此类,或者在类定义前申明这个[RemoteClass]元数据标签。

假定你的程序要把用户信息作为一个对象进行显示,可过一段时间被同一个程序或者被其他程序载入,这些程序应已知道如何处理该对象,要表现用户信息的自定义对象看起来大概是下面这样:

+展开
-ActionScript
package com.oreilly.flexcookbook {
[RemoteClass]
[Bindable]
public  class UserData {
public  var firstName:String;
public  var lastName:String;
public  var age:Number;
public  var sessionLength:Number;
public  function UserData( firstName:String =  "",lastName:String =  ""){
this.firstName = firstName;
this.lastName = lastName;
}
}
}


每次你的程序被用户打开时,一个新的UserData对象被创建,等待用户输入信息,通常可以保存这些信息以特定的格式保存到文本文件上,但是你也可以序列化对象到文件上,从而可轻易的以对象类型读取,不必要解析字符串,重置UserData新实例属性。要序列化对象且通过反序列化保留其属性值,需要使用[RemoteClass]元数据标签注册它。

在类申明前插入[RemoteClass] 元数据标签,可启动此类在使用AMF序列化和反序列化中能保持类型信息和属性值。你也可以在变量定义前加上[Transient]元数据标签,指示此变量不会被序列化。比如上面例子中的sessionLength属性每次程序运行时都会更新,因为没必要进行保存,你可以把此属性标记为transient属性拒绝被序列化:

+展开
-ActionScript
package com.oreilly.flexcookbook {
[RemoteClass]
public  class UserData {
public  var firstName:String;
public  var lastName:String;
public  var age:Number;
[Transient]
public  var sessionLength:Number;
public  function UserData( firstName:String =  "",lastName:String =  ""){
this.firstName = firstName;
this.lastName = lastName;
}
}
}


使用FileStream.writeObject方法把序列化自定义对象写到文件里,当使用writeObject和readObject 写入和读取二进制数据默认所用的编码格式是AMF 3 规范。通过设置FileStream.objectEncoding属性,你可以使用AMF 0 格式,下面的例子保存用户信息到扩展名为.user的文件上:

+展开
-XML
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxmllayout="vertical">
<mx:Script>
<![CDATA[
import com.oreilly.flexcookbook.UserData;
private  var userData:UserData =  new UserData();
private  static  const EXT:String =  ".user" ;
private  function submitHandler(): void {
userData.firstName = firstField.text;
userData.lastName = lastField.text;
userData.age = ageField.value;
saveUserData();
}
private  function saveUserData(): void
{
var fnm:String = userData.firstName +  "_"+userData.lastName + EXT;
var file:File =File.desktopDirectory.resolvePath( fnm );
var stream:FileStream =  new FileStream();
stream.open( file, FileMode.WRITE );
stream.writeObject( userData );
stream.close();
}

]]>
</mx:Script>
<mx:Form>
<mx:FormItem label="First Name:">
<mx:TextInput id="firstField"
change="{submitBtn.enabled = firstField.text != ''}"/>

</mx:FormItem>
<mx:FormItem label="Last Name:">
<mx:TextInput id="lastField"
change="{submitBtn.enabled = lastField.text != ''}"/>

</mx:FormItem>
<mx:FormItem label="Age:">
<mx:NumericStepper id="ageFieldminimum="18maximum="110" />
</mx:FormItem>
<mx:Button id="submitBtnlabel="submitenabled="falseclick="submitHandler();" />
</mx:Form>
</mx:WindowedApplication>


当用户输入并提交信息后,submitHandler事件处理器被调用,UserData对象被更新,接着调用saveUserData方法。在saveUserData方法中,用UserData实例的firstName和lastName属性组成文件路径,文件被保存到桌面上,扩展名为.user。当反序列化时,文件被再次打开,对象属性值将被会恢复。下面的例子扩展了之前的程序,提供对打开.user文件的支持:

+展开
-XML
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxmllayout="vertical">
<mx:Script>
<![CDATA[
import com.oreilly.flexcookbook.UserData;
[Bindable]
private  var userData:UserData =  new UserData();
private  var file:File = File.desktopDirectory;
private  var filter:FileFilter =  new FileFilter( "User File""*.user");
private  static constEXT:String =  ".user";
private  function submitHandler(): void{
userData.firstName = firstField.text;
userData.lastName = lastField.text;
userData.age = ageField.value;
saveUserData();
}
private  function saveUserData(): void {
var fnm:String = userData.firstName +  "_" + userData.lastName + EXT;
var file:File = File.desktopDirectory.resolvePath( fnm );
var stream:FileStream =  new FileStream();
stream.open( file, FileMode.WRITE );
stream.writeObject( userData );
stream.close();
}
private  function openHandler(): void {
file.browseForOpen(  "Open User", [filter] );
file.addEventListener( Event.SELECT, selectHandler );
}
private  function selectHandler( evt:Event ): void {
var stream:FileStream =  new FileStream();
stream.open( file, FileMode.READ );
userData = stream.readObject();
}

]]>
</mx:Script>
<mx:Form>
<mx:FormItem label="First Name:">
<mx:TextInput id="firstField"
text="{userData.firstName}"
change="{submitBtn.enabled = firstField.text != ''}"/>

</mx:FormItem>
<mx:FormItem label="Last Name:">
<mx:TextInput id="lastField"
text="{userData.lastName}"
change="{submitBtn.enabled = lastField.text != ''}"/>

</mx:FormItem>
<mx:FormItem label="Age:">
<mx:NumericStepper id="ageFieldvalue="{userData.age}minimum="18maximum="110" />
</mx:FormItem>
<mx:Button id="submitBtnlabel="submitenabled="falseclick="submitHandler();"
/>

</mx:Form>
<mx:HRule width="100%" />
<mx:Button label="openclick="openHandler();" />
</mx:WindowedApplication>


当用户点击open按钮时,File.browseForOpen方法会打开一个对话框,并设置了过滤器只显示.user 扩展名的文件。当一个文件被选中后, selectHandler 方法被调用, 通过FileStream.readObject方法将文件读入到缓冲区,readObject方法将反序列化UserData对象,通过数据绑定将保存的数据显示到表单。

FileStream.writeObject和FileStream.readObject方法提供了很多方法用于序列化数据对象到文件系统上。通过[RemoteClass]元数据标签注册类即可用AMF将类进行编码为二进制格式。

如果你是从文本文件中处理载入和解析键--值对自定义对象,那么序列化自定义对象将大大减少开发开销

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值