Adobe AIR and Flex - 保存序列化对象文件(译)

 

        创建任何桌面应用程序几乎总是需要在本地存储数据,通过Adobe AIR我们有几下面几个选择,一个是我们能够使用内置的 SQLite 数据库支持,对于少量的数据这是大材小用了。另外一个选择是我们通过把数据转换成XML格式,并写入文件中,问题是,如果我们需要一个对象,不得不写一些解码器来转换这个XML。还有另一个选择是在Adobe AIR中,我们序列化一个对象到byte数组,并且写入文件。

         好的,我们可以写一个对象到文件中,我们选择那种呢?有两件事情,首先,作为一个byte数组,数组将是非常小的,有利于节省保存空间。最后,我们通过一个或者两个方法来序列化这个类型对象,并且返回类型对象。所以,我们选择最后一种。

       在本教程中,我们将在应用程序关闭的时候把用户的一些偏好数据保存起来,在下次程序打开的时候,并重新读取它。所以,让我们先看看后面将要保存文件的这个对象。

package
{
  [RemoteClass]
  public class UserPrefs
  {
    public var name:String;
    public var appPosX:Number;
    public var appPosY:Number;
    public var appWidth:Number;
    public var appHeight:Number;
  }
}

嗯,应该看到上面有个与众不同的地方。[RemoteClass]元数据标签Adobe对这个元标签有一个很好的描述,在下面:

Use the [RemoteClass] metadata tag to register 
the class with Flex so that Flex preserves 
type information when a class instance is serialized by using Action Message Format (AMF).
使用这个[RemoteClass]元标签来注册的flex类来保存类型信息。当这个类的对象被序列化的时候使用AMF通讯协议

     主要的,我们序列化这个对象的时候,需要这个标签来确定它的类型。并且阅读这个对象的所有人都可以看出它的类型(像 UserPrefs)。

     为了保存这个对象到文件中,我们仅仅需要几行代码就可以了。为了处理这个问题,我创建了一个拥有一些静态方法的类。类名为FileSerializer,将拥有写对象到文件,

读文件到对象的方法。

package com.paranoidferret.util
{
  import flash.filesystem.File;
  import flash.filesystem.FileMode;
  import flash.filesystem.FileStream;

  public class FileSerializer
  {
    public static function writeObjectToFile(object:Object, fname:String):void
    {
      var file:File = File.applicationStorageDirectory.resolvePath(fname);

      var fileStream:FileStream = new FileStream();
      fileStream.open(file, FileMode.WRITE);
      fileStream.writeObject(object);
      fileStream.close();
    }
  }
}

  在上面你可能注意到这个方法有两个参数。objectfname ,第一个是写入文件的对象,第二个是写入文件的文件名。方法的第一行是得一个我们将要写入的文件。

我们首先创建了一个FileStream(文件流),并且打开了这个文件的写操作。然后我们使用方法writeObject写这个对象到文件,然后关闭这个文件流。是的,它确实容易。

   现在我们能写一个对象到文件,我们也应该创建一个方法来阅读这个文件。下面是一个完整的FileSerializer 类,我们添加了一个新的方法。

package com.paranoidferret.util
{
  import flash.filesystem.File;
  import flash.filesystem.FileMode;
  import flash.filesystem.FileStream;

  public class FileSerializer
  {
    public static function writeObjectToFile(object:Object, fname:String):void
    {
      var file:File = File.applicationStorageDirectory.resolvePath(fname);

      var fileStream:FileStream = new FileStream();
      fileStream.open(file, FileMode.WRITE);
      fileStream.writeObject(object);
      fileStream.close();
    }

    public static function readObjectFromFile(fname:String):Object
    {
      var file:File = File.applicationStorageDirectory.resolvePath(fname);

      if(file.exists) {
        var obj:Object;
        var fileStream:FileStream = new FileStream();
        fileStream.open(file, FileMode.READ);
        obj = fileStream.readObject();
        fileStream.close();
        return obj;
      }
      return null;
    }
  }
}
View Code

      读对象的方法基本遵循同样的流程,除了它从文件读对象的方法readObject,然后关闭流,并返回这个对象。如果不能读取这个文件,或者文件中的数据不正确,readObject将抛出一个error。如果你想处理这里,可以try catch这块。

      接下来,让我们看看如何使用它,我们构建一个应用程序,需要记住你最后一次打开它的状态。我们从上面对象很容易做这样的事情它甚至可能看起来像下面这样。

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication 
  xmlns:mx="http://www.adobe.com/2006/mxml" 
  layout="absolute"
  width="300" height="200"
  creationComplete="init()"
  closing="closing()">
  <mx:Script>
    <![CDATA[
      import com.paranoidferret.util.FileSerializer;

      private var up:UserPrefs;

      private function init():void
      {
        this.up = FileSerializer.readObjectFromFile("prefs.up") as UserPrefs;
        if(up) {
          this.nativeWindow.x = up.appPosX;
          this.nativeWindow.y = up.appPosY;
          this.nativeWindow.width = up.appWidth;
          this.nativeWindow.height = up.appHeight;
          this.nativeWindow.title = up.name;
        } else {
          this.up = new UserPrefs();
        }
      }

      private function closing():void
      {
        this.up.name = "The Fattest";
        this.up.appPosX = this.nativeWindow.x;
        this.up.appPosY = this.nativeWindow.y;
        this.up.appWidth = this.nativeWindow.width;
        this.up.appHeight = this.nativeWindow.height;
        FileSerializer.writeObjectToFile(this.up, "prefs.up");
      }
    ]]>
  </mx:Script>
</mx:WindowedApplication>

       在上面的代码,我们检查是否有用户的喜好。在creationComplete 里读取文件。如果我们得到了返回的Object ,然后把它转换为UserPrefs  ,然后从文件里更新应用程序的nativeWindow大小和位置。

    

 

  

 

 

 

 

posted @ 2013-07-18 15:02  羊皮稿  阅读(1195)  评论(0编辑  收藏  举报