当我们编写AE程序时,通常会遇到需要存储某个AE对象的情况,比如Layer,Element,Map,Legend,NorthArrow等等这些。举个例子说明一下:在我们编辑Featurelayer时,我们可以容易的将Feature存储在Featureclass中;同样,如果我们向Graphicscontainer中添加了Element,我们也希望可以容易的存储Element,这样每次加载时可以将Element顺利显示出来,但是不巧的是,AE中并没有提供存储Element的方法。这个时候,我们就需要将Graphicscontainer序列化成文件,这样就可以达到存储的目的了。Featureclass存储成shapefile也好,Geodatabase也罢,都是一种文件的组织形式,也都是一种特殊意义上的序列化。
下面,介绍序列化的方法:
首先可以序列化的对象必须实现了IPersistStream接口,其中IPersistStream接口是Windos中的接口,派生自 IPersist,并增加了4个函数,从流(IStream)中读写组件属性信息。下面是各个函数的意义:
IsDirty() | 组件内部属性是否发生了变化。为调用者是否需要保存信息提供依据 |
Load() | 从 IStream 中读入信息,初始化组件属性 |
Save() | 把属性信息保存到 IStream 中 |
GetSizeMax() | 返回信息尺寸,以便调用者事先开辟空间 |
/// <summary>
/// ArcGIS对象序列化成二进制
/// </summary>
/// <param name="pObject"></param>
/// <returns></returns>
public static byte[] ReadObjectToBytes(object pObject)
{
byte[] defaultBytes = null;
if (pObject is IPersistStream)
{
IPersistStream persistStream = pObject as IPersistStream;
IObjectStream pObjStream = new ObjectStreamClass();
IMemoryBlobStream pBlobStream = new MemoryBlobStreamClass();
pObjStream.Stream = pBlobStream;
persistStream.Save(pObjStream, 0);
int n = (int)pBlobStream.Size;
defaultBytes = new byte[n];
object obj2 = null;
IMemoryBlobStreamVariant pBlobVariant = pBlobStream as IMemoryBlobStreamVariant;
pBlobVariant.ExportToVariant(out obj2);
defaultBytes = (byte[])obj2;
}
return defaultBytes;
}
/// <summary>
/// 二进制反序列化成ArcGIS对象
/// </summary>
/// <param name="bytes"></param>
/// <param name="pObject"></param>
public static void ReadObjectFromBytes(byte[] bytes, object pObject)
{
if (pObject is IPersistStream)
{
IPersistStream pPersistStream = pObject as IPersistStream;
IMemoryBlobStream2 pBlobStream = new MemoryBlobStreamClass();
pBlobStream.ImportFromMemory(ref bytes[0], (uint)bytes.Length);
IObjectStream pObjStream = new ObjectStreamClass();
pObjStream.Stream = pBlobStream;
pPersistStream.Load(pObjStream);
}
}
/// <summary>
/// 读取ArcGIS BLOB类型属性到byte数组
/// </summary>
/// <param name="blobValue">字段值</param>
/// <returns></returns>
public static byte[] ReadEsriBlobToBytes(object blobValue)
{
if (blobValue == null || blobValue == DBNull.Value)
{
return null;
}
IMemoryBlobStream2 pBlobStream = new MemoryBlobStreamClass();
pBlobStream = (IMemoryBlobStream2)blobValue;
int n = (int)pBlobStream.Size;
byte[] bytes = new byte[n];
object obj = null;
IMemoryBlobStreamVariant pBlobVariant = pBlobStream as IMemoryBlobStreamVariant;
pBlobVariant.ExportToVariant(out obj);
bytes = (byte[])obj;
return bytes;
}
/// <summary>
/// 将AE中实现了IPersistStream接口的对象序列化为二进制文件
/// </summary>
/// <param name="FilePath">如C:\file.blb</param>
/// <param name="pObject"></param>
/// <returns></returns>
public static bool WriteObj(string FilePath, object pObject)
{
bool result = false;
if (pObject is IPersistStream)
{
IPersistStream persistStream = pObject as IPersistStream;
IObjectStream pObjStream = new ObjectStreamClass();
IMemoryBlobStream pBlobStream = new MemoryBlobStreamClass();
pObjStream.Stream = pBlobStream;
persistStream.Save(pObjStream, 0);
try
{
pBlobStream.SaveToFile(FilePath);
result = true;
}
catch { }
}
return result;
}
/// <summary>
/// 序列化AE对象为字符串,在线程间传递
/// </summary>
public static string SerialsAEObject(IWorkspace pWorkspace)
{
try
{
IXMLStream pStream = new XMLStreamClass();
IXMLWriter pWriter = new XMLWriterClass();
pWriter.WriteTo(pStream as IStream);
IXMLSerializer pSerializer = new XMLSerializerClass();
//pWorkspace不能序列化,会报错
pSerializer.WriteObject(pWriter, null, null, "", "", pWorkspace.ConnectionProperties);
return pStream.SaveToString();
}
catch (Exception ex)
{
return "";
}
}
public static IWorkspace DeSerialsAEObject(string strObj,string PassWord)
{
try
{
IXMLStream pStream = new XMLStreamClass();
pStream.LoadFromString(strObj);
IXMLReader pReader = new XMLReaderClass();
pReader.ReadFrom(pStream as IStream);
IXMLSerializer pSerializer = new XMLSerializerClass();
IPropertySet pPropSet = pSerializer.ReadObject(pReader, null, null) as IPropertySet;
pPropSet.SetProperty("PASSWORD",PassWord);//反序列化后密码是空,需要重新赋值,要不会弹出连接参数界面
IWorkspaceFactory workspaceFactory = new ESRI.ArcGIS.DataSourcesGDB.SdeWorkspaceFactoryClass();
IWorkspace pWS = workspaceFactory.Open(pPropSet, 0);
return pWS;
}
catch (Exception ex)
{
return null;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义