最近开发一个工具,需要使用临时文件,对中间结果进行存储,格式为GDB文件,但是程序内死活删不掉该GDB文件;最后找到了一个半拉子解决方案,就把自己跳过的坑总结一下,以飨读者。
有兴趣的读着还可以关注之前写过的以下两篇文章:
基于C#的ArcEngine二次开发39:GP工具的使用--界面、参数及示例代码
基于C#的ArcEngine二次开发29:GDB文件操作及异常处理
目录
1 创建与使用
2 删除尝试
2.1 IDataset删除法
2.2 IFeatureWorkspaceManage接口移除要素类
2.3 解锁数据库
2.4 清理COM对象
2.5 杀进程删文件
2.5.1 杀死线程
2.5.2 删除目录
//创建GDB文件对象
CreateFileGDB process1 = new CreateFileGDB {out_folder_path = @"D:\新建文件夹", out_name = "temp.gdb"}
GP.Execute(processor1, null);//将创建的GDB文件加入到GP工具中
注意上述代码中为out_folder_path设定的目录必须是已存在的目录,否则在使用GP工具执行时,会报错:对COM组件的调用返回了错误 HRESULT E_FAIL
使用
IWorkspaceFactory pWsFactory = new ShapefileWorkspaceFactoryClass();
IFeatureWorkspace pWorkSpace = pWsFactory.OpenFromFile(path, 0) as IFeatureWorkspace;
将IWorkspace转为IDataset,然后使用IDataset.Delete();进行删除。最好不要使用System.IO.File.Delete(path); 根据mdb或FileGDB的路径删除,这种方法可能删除不掉或者删不干净。
注意:删除该workspace之前需要将使用到的FeatureClass,Feature,FeatureCursor,Field等AO对象先释放掉,可以使用System.Runtime.InteropServices.Marshal.FinalReleaseComObject();释放。
IDataset dataset = pWorkspace as IDataset;
dataset.Delete();
删除GDB数据库中指定数据集的指定要素类,GDB数据库路径已知
public void DeleteFeatureClass(string featueClassName)
{
//打开GDB文件
IWorkspaceFactory worFact =new FileGDBWorkspaceFactory();
IWorkspace workspace = worFact.OpenFromFile("路径", 0);
IFeatureWorkspace featureWorkspace = workspace as IFeatureWorkspace;
//根据名称删除数据库要素
IFeatureWorkspaceManage featureWorkspaceMange = (IFeatureWorkspaceManage)featureWorkspace;
IEnumDatasetName enumDatasetName = workspace.get_DatasetNames(esriDatasetType.esriDTFeatureClass);
IDatasetName datasetName = null;
while ((datasetName = enumDatasetName.Next()) != null)
{
if (datasetName.Name.Equals(featueClassName))
{
featureWorkspaceMange.DeleteByName(datasetName);//删除指定要素类
break;
}
}
}
IWorkspaceFactoryLockControl ipWsFactoryLock = IWorkspaceFactoryLockControl)pWsFactory; //pWsFactory可以是GDB/SHP/MDB
if(ipWsFactoryLock.SchemaLockingEnabled)
{
ipWsFactoryLock.DisableSchemaLocking();
}
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);
注意 Marshal.FinalReleaseConObject 与 Marshal.ReleaseConObject 的区别:
前者是直接将对象的引用计数减到0;后者只是引用计数减1
public static int FinalReleaseComObject (object o)
{
while (ReleaseComObject (o) != 0) ;
return 0;
}
下面的方法 无法删除timestamps文件,原因未知,欢迎大神指点;为什么所有文件都可以删除但是只有这个文件删不掉。
这个地方可能报错 【32位进程无法访问64位进程模块】
Process[] pcs = Process.GetProcesses();
foreach (Process p in pcs)
{
if (p.MainModule.FileName == "你的文件路径")
{
p.Kill();
}
}
此方法可能报错:【文件正由另一进程使用,该进程无法访问该文件】
///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);
}
}