天天看点

有关AE对象的序列化(C#)

AE中提供了IPersistStream接口进行AE对象的序列化,所有继承了IPersistStream接口的AE对象都可以使用IPersistStream进行对象的序列化。它的使用方法如下:

void SerializeArcGisObject(object gisObj)

{

   //转换成IPersistStream对象

ESRI.ArcGIS.esriSystem.IPersistStream ps = gisObj as ESRI.ArcGIS.esriSystem.IPersistStream;

//如果是继承了IPersistStream接口,则序列化

if (ps != null)

{

     //定义一种流对象;这里使用了MemoryBlobStreamClass

      ESRI.ArcGIS.esriSystem.MemoryBlobStreamClass mbsc = new ESRI.ArcGIS.esriSystem.MemoryBlobStreamClass();

      //把对象保存到流中

ps.Save(mbsc, 0);

//保存成文件

       mbsc.SaveToFile(tempFileName);

    }

}

使用这个序列化时需要注意,有时在ps.Save(mbsc, 0)时会提示无限循环的错误,这时需要检查序列化对象是否存在嵌套的成员(类A包含类B成员,而B有包含了A的对象),例如AE的比例尺元素的对象,在该对象中是存有当前的地图对象,而地图对象又有比例尺元素的这个对象,所以一般会提示错误。这时在序列化对象时,需要把序列化对象的这种成员的值去掉,再进行序列化。例如上面的比例尺对象,把比例尺的Map成员赋成null,再进行序列化(注意:一般要先拷贝对象后,再把成员赋成null值,否则可能出现内存访问错误,使用IObjectCopy进行拷贝)。

上面说的是序列化,那么在序列化完成后,反序列化也就必不可少了。

object DeserializeArcGisObject(string filename,Guid guid)

{

//定义一种流对象;这里使用了MemoryBlobStreamClass

//使用流读取文件

                ESRI.ArcGIS.esriSystem.MemoryBlobStreamClass mbsc = new ESRI.ArcGIS.esriSystem.MemoryBlobStreamClass();

//使用流读取文件

mbsc.LoadFromFile(filename);

//实例化对象,这里需要知道这个文件存的是那个对象,可以

//这里使用COM的Guid来标示(起始可以自己定义一种文件,文件头存Guid)

//使用COM的Guid获取Com类型

Type comType = Type.GetTypeFromCLSID(guid, false);

//通过Type实例化对象

            ESRI.ArcGIS.esriSystem.IPersistStream ips = (ESRI.ArcGIS.esriSystem.IPersistStream)Activator.CreateInstance(comType);

  ips.Load(objStream);

   return ips;

}

使用这个方式反序列化时,如果想把反序列的对象转换成实体类(Guid一样的)的对象,是无法进行转换的,只能转换成对应的接口。如果想转换的话,可以使用内存拷贝的方式进行转换。有关内存拷贝可以参考IObjectCopy的方法。