基于C#的ArcEngine二次开发29:GDB文件操作及异常处理(下)

简介: 基于C#的ArcEngine二次开发29:GDB文件操作及异常处理

2.2.3 完善代码

            IQueryFilter filter = new QueryFilterClass();
            filter.WhereClause = "";
            IFeatureCursor pFeaturnCuesor = srcFeatureClass.Search(filter, false);
            IFeature pFeature = pFeaturnCuesor.NextFeature();
            IFeatureClassLoad dstFeaLoad = dstFeatureClass as IFeatureClassLoad;
            dstFeaLoad.LoadOnlyMode = true;
            while (pFeature != null)
            {
                IFeature dstFea = dstFeatureClass.CreateFeature();
                dstFea.Shape = pFeature.Shape;
                dstFea.Store();
                pFeature = pFeaturnCuesor.NextFeature();
            }

3 GDB目录删除与资源释放

3.1 删除gdb文件

gdb实际上是一个文件夹,所以要使用文件夹删除的方式删除

///dir为要删除的文件夹
public void deleteDir(string dir)
{
    try
    {
        Directory.Delete(dir, true);
    }
    catch
    {
        foreach (string file in Directory.GetFiles(dir))
        {
            FileInfo info = new FileInfo(file);
            info.Attributes = FileAttributes.Normal;
            File.Delete(file);
        }
        Directory.Delete(dir);
     }
}

代码二:

将IWorkspace转为IDataset,然后使用IDataset.Delete();进行删除。最好不要使用System.IO.File.Delete(path); 根据mdb或FileGDB的路径删除,这种方法可能删除不掉或者删不干净。

IDataset dataset = pWorkspace as IDataset; 
dataset.Delete();

注意:删除该workspace之前需要将使用到的FeatureClass,Feature,FeatureCursor,Field等AO对象先释放掉,可以使用System.Runtime.InteropServices.Marshal.FinalReleaseComObject();释放。

IWorkspaceFactory pWF = new FileGDBWorkspaceFactoryClass();
IWorkspace pW = pWF.OpenFromFile(gdbPath);
IFeatureWorkspace pWorkspace = pW as IFeatureWorkspace;
.....
IDataset dataset = pWorkspace as IDataset;
dataset.Delete();

3.2 资源解除占用

3.2.1 杀死文件:

            Process[] pcs = Process.GetProcesses();
            foreach (Process p in pcs)
            {
                if (p.MainModule.FileName == "你的文件路径")
                {
                    p.Kill();
                }
            } 

3.2.2 解除资源锁定:

ArcEngine /AO创建IWorkSpaceFactory的两种方式:
//第一种使用ae的工厂方法:
 IWorkspaceFactory pWsFactory = new ShapefileWorkspaceFactoryClass();
 IFeatureWorkspace  pWorkSpace = pWsFactory.OpenFromFile(path, 0) as IFeatureWorkspace;
//第二种使用C#的动态创建类型的方法:
Type typeObj=Type .GetTypeFromProgID("esriWorkspaceType.ShapefileWorkspaceFactoryClass" );
IWorkspaceFactory pWsFactory = (IWorkspaceFactory)Activator.CreateInstance(typeObj,null);
IFeatureWorkspace  pWorkSpace = pWsFactory.OpenFromFile(path, 0) as IFeatureWorkspace;
//关闭资源锁定  
IWorkspaceFactoryLockControl ipWsFactoryLock = IWorkspaceFactoryLockControl)pWsFactory; //pWsFactory可以是GDB/SHP/MDB
if(ipWsFactoryLock.SchemaLockingEnabled)
{
    ipWsFactoryLock.DisableSchemaLocking();
}

3.2.3 资源释放问题


AE中对MDB,SDE等数据库操作时,打开后却往往不能及时释放资源,导致别人操作提示对象被锁定。很多帖子说了很多原理,看的也烦且不实用,比如一句话概括的用System.Runtime.InteropServices.Marshal.ReleaseComObject(object o) 释放,说的很不清楚,很多人试过觉的释放不掉。事实上,的确是用该方法,但释放的技巧在于,新建几个AE对象就要逐步释放几个,例如:

IWorkspaceFactory Fact = new AccessWorkspaceFactoryClass ();
IFeatureWorkspace Workspace = Fact.Open(Propset,0) as IFeatureWorkspace;
IFeatureClass Fcls = Workspace.OpenFeatureClass ("District");
IFeatureLayer Fly = new FeatureLayerClass();
……
IFeature pf
IField pfield
……

再对象运行结束时释放,如:

System.Runtime.InteropServices.Marshal.ReleaseComObject(Fact)
System.Runtime.InteropServices.Marshal.ReleaseComObject(Workspace);
System.Runtime.InteropServices.Marshal.ReleaseComObject(Fcls);
System.Runtime.InteropServices.Marshal.ReleaseComObject(Fly);
System.Runtime.InteropServices.Marshal.ReleaseComObject(pf);
System.Runtime.InteropServices.Marshal.ReleaseComObject(pfield);

看到吧,千万不要以为你释放了等级最高的 IWorkspaceFactory, IWorkspace就算完事了。没办法,AE有时就这么难以理解的麻烦。

4 从gdb中拷贝图层到mdb中

主要是为了调用 IFeatureDataConverter.ConvertFeatureClass 方法:

public IEnumInvalidObject ConvertFeatureClass (
    IFeatureClassNameInputDatasetName,
    IQueryFilterInputQueryFilter,
    IFeatureDatasetNameoutputFDatasetName,
    IFeatureClassNameoutputFClassName,
    IGeometryDefOutputGeometryDef,
    IFieldsOutputFields,
    stringconfigKey,
    intFlushInterval,
    intparentHWND);

为了给该函数提供参数,进行如下步骤拆解:

从gdb中获取感兴趣图层

从gdb中获取感兴趣图层的名称

打开mdb文件

判断要拷贝文件是否存在,存在删除

将gdb待拷贝图层字段赋值到mdb目标图层

设置集合定义

设置查询条件

调用转换函数

4.1 从gdb中获取感兴趣图层

  • 打开工作空间工厂
  • 从文件中打开工作空间,将工作空间跳转为要素工作空间
  • 从要素工作空间中打开要素类
            IWorkspaceFactory workspaceFactory = new ESRI.ArcGIS.DataSourcesGDB.FileGDBWorkspaceFactoryClass();
            IWorkspace iworkspace = iworkspaceFactory.OpenFromFile(inPath, 0);
            IFeatureWorkspace ifeatureWorkspace = (IFeatureWorkspace)iworkspace;
            IFeatureClass ipFeaterClass = ifeatureWorkspace.OpenFeatureClass(checkLayerName);

4.2 获取gdb感兴趣图层的图层名

            IWorkspaceName inWorkspaceName = (inWorkspace as IDataset).FullName as IWorkspaceName ;     
            IFeatureClassName inFeatureClassName = new FeatureClassNameClass();
            IDatasetName inDatasetName = (IDatasetName)inFeatureClassName;
            inDatasetName.WorkspaceName = inWorkspaceName;
            inDatasetName.Name = gdbLayerName;

4.3 打开mdb文件

            IWorkspaceFactory oworkspaceFactory = new AccessWorkspaceFactory();
            IWorkspace oworkspace = oworkspaceFactory.OpenFromFile(inPath, 0);
            IFeatureWorkspace ofeatureWorkspace = (IFeatureWorkspace)workspace;
            IFeatureClass poFeaterClass = ofeatureWorkspace.OpenFeatureClass(mdbLayerName);

4.4 判断要拷贝到mdb的文件是否存在

            IWorkspace2 oworkspace2 = (IWorkspace2)oworkspace;
            if (oworkspace2.get_NameExists(esriDatasetType.esriDTFeatureClass, checkLayerName + "_超出图层检查结果"))
            {
                IFeatureClass pFC = ofeatureWorkspace.OpenFeatureClass(checkLayerName + "_超出图层检查结果");
                IDataset pDS = pFC as IDataset;
                pDS.Delete();
            }

4.5 输出mdb图层名设置

            IWorkspaceName ouWorkspaceName = (ouWorkspace as IDataset).FullName as IWorkspaceName ;     
            IFeatureClassName ouFeatureClassName = new FeatureClassNameClass();
            IDatasetName ouDatasetName = (IDatasetName)ouFeatureClassName;
            ouDatasetName.WorkspaceName = ouWorkspaceName;
            ouDatasetName.Name = mdbLayerName;

4.6 字段赋值

            IFieldChecker fieldChecker = new FieldCheckerClass();
            fieldChecker.InputWorkspace = iworkspace;//输入数据集工作空间
            fieldChecker.ValidateWorkspace = ouWorkpace;//输出工作空间
            IFields outFeatureClassFields;
            IEnumFieldError enumFieldError;            
            fieldChecker.Validate(inFeatureClassFields, out enumFieldError, out outFeatureClassFields);

4.7 设置几何定义

            IField geometryField =  outFeatureClassFields.get_Field(outFeatureClassFields.FindField(inFeatureClass.ShapeFieldName));
            IGeometryDef geometryDef = geometryField.GeometryDef;

4.8 满足条件的数据查询

            //Set up the IQueryFilter to convert all the features by leaving a blank WhereClause
            QueryFilter qf = new QueryFilterClass();
            qf.WhereClause = "";

4.9 数据转换

IFeatureDataConverter fctofc = new FeatureDataConverterClass();
IEnumInvalidObject enumErrors = fctofc.ConvertFeatureClass(inFeatureClassName, qf, null, outFeatureClassName, geometryDef, outFeatureClassFields, "", 1000, 0);

参考资料:从FileGDB导出shp

5 其他代码积累

5.1 添加或删除字段

  /// <summary>  
    /// 删除属性表字段  
    /// </summary>  
    /// <param name="layer">需要添加字段的IFeatureLayer</param>  
    /// <param name="fieldName">添加的字段的名称</param>  
    /// <returns></returns>  
    static public bool DeleteField(IFeatureLayer layer, string fieldName)  
    {  
        try  
        {  
            ITable pTable = (ITable)layer;  
            IFields pfields;  
            IField pfield;  
            pfields = pTable.Fields;  
            int fieldIndex = pfields.FindField(fieldName);  
            pfield = pfields.get_Field(fieldIndex);  
            pTable.DeleteField(pfield);  
            return true;  
        }  
        catch (Exception ex)  
        {  
            return false;  
        }  
    }  
/// <summary>  
 /// 添加字段  
 /// </summary>  
 /// <param name="layer"></param>  
 /// <param name="fieldName"></param>  
 /// <param name="filedType"></param>  
 /// <param name="fieldLength"></param>  
 /// <returns></returns>  
 static public bool AddField(IFeatureLayer layer, string fieldName, esriFieldType filedType, int fieldLength)  
 {  
     try  
     {  
         IFields pFields = layer.FeatureClass.Fields;  
         // IFieldsEdit pFieldsEdit = pFields as IFieldsEdit;  
         IFieldEdit pFieldEdit;  
         pFieldEdit = new FieldClass();  
         if (fieldName.Length > 5)  
             pFieldEdit.Name_2 = fieldName.Substring(0, 5);  
         else  
             pFieldEdit.Name_2 = fieldName;  
         pFieldEdit.Type_2 = filedType;  
         pFieldEdit.Editable_2 = true;  
         pFieldEdit.AliasName_2 = fieldName;  
         pFieldEdit.Length_2 = fieldLength;  
         ITable pTable = (ITable)layer;  
         pTable.AddField(pFieldEdit);  
         return true;  
         //   pFieldsEdit.AddField((IField)pFieldEdit);  
     }  
     catch (Exception ex)  
     {  
         return false;  
     }  
 }  
相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
相关文章
|
6月前
|
C#
C# 文件操作(全部) 追加、拷贝、删除、移动文件、创建目录
C# 文件操作(全部) 追加、拷贝、删除、移动文件、创建目录
89 0
|
6月前
|
程序员 C#
深入理解 C# 编程:枚举、文件处理、异常处理和数字相加
枚举是一个特殊的“类”,表示一组常量(不可更改/只读变量)。 要创建枚举,请使用 enum 关键字(而不是 class 或 interface),并用逗号分隔枚举项:
66 0
|
2月前
|
安全 C# 开发者
C# 一分钟浅谈:文件操作与文件流详解
【9月更文挑战第4天】在日常开发中,文件的读写是基本而重要的任务。C# 通过 `System.IO` 命名空间提供了多种工具,如 `FileStream`、`StreamReader` 和 `StreamWriter` 等,用于处理文件和流。本文从基础概念入手,详细介绍了这些类的使用方法,并讨论了常见错误及其避免策略,包括文件不存在、权限问题和文件被占用等。通过示例代码,展示了如何创建、读取文件以及进行二进制数据操作,并强调了异常处理和性能优化的重要性。掌握这些技巧对于提升编程能力至关重要。
158 2
|
2月前
|
运维 C# UED
C# 一分钟浅谈:异常处理的最佳实践
【9月更文挑战第5天】在软件开发中,异常处理对保证程序稳定性和用户体验至关重要。本文从基础概念入手,详细讲解C#中的异常处理策略,并通过代码示例说明如何有效实现异常管理。文章涵盖`try`、`catch`和`finally`块的使用,探讨常见问题如忽略异常和过度捕获,并提出最佳实践建议,如使用具体异常类型、记录异常信息及优雅地处理异常,助力开发者构建更健壮的应用程序。
129 0
|
3月前
|
消息中间件 开发框架 安全
WPF/C#:异常处理
WPF/C#:异常处理
48 0
|
C#
C#异常处理
C#异常处理
62 0
|
C#
使用C#进行文件操作
在许多应用程序中,文件操作是常见的任务之一。无论是读取文件内容、写入数据,还是创建、移动和删除文件,C# 编程语言都提供了强大且易于使用的文件操作功能。本篇博客将介绍如何使用C#来进行基本的文件操作。
67 0
|
开发框架 IDE Java
【C#本质论 十二】异常处理
【C#本质论 十二】异常处理
84 0
基于C#的ArcEngine二次开发56:双击属性表跳转目标要素并闪烁
基于C#的ArcEngine二次开发56:双击属性表跳转目标要素并闪烁
基于C#的ArcEngine二次开发56:双击属性表跳转目标要素并闪烁