如何用C# LINQ读取PRJ文件检测多字符串以区分ESRI SHP文件
问题描述
本人熟悉SAS/Python,目前临时顶替C#开发岗位。公司软件需要预处理.prj文件来确认文件类型,但业务所需的正确.prj文件和GIS映射用的ESRI SHP的.prj文件扩展名相同,容易混淆。需要读取文件开头,检测是否包含GEOGCS[、PROJCS[、GEOCCS[这类字符串来排除ESRI SHP的.prj文件。现有测试控制台代码只能检测单个关键词,尝试用列表等方式通过LINQ实现多搜索词检测但未成功,求解决方案。
现有测试代码
using System; using System.IO; // 补充原代码遗漏的命名空间 using System.Linq; using System.Collections.Generic; namespace TestPgm { public class Check_PRJ { // 检查PRJ文件是否为GIS SHP的配套文件 public static void Main() { Console.Write("请输入文件路径及名称:"); string fname = Console.ReadLine(); string prj_flag = "GEOGCS["; string dir = new FileInfo(fname).DirectoryName.ToString(); if (IsPrjFile(fname, prj_flag)) Console.WriteLine("该PRJ文件是GIS SHP文件的组成部分,并非损坏文件,请勿删除。"); else Console.WriteLine("该文件是正确的PRJ文件。"); } static bool IsPrjFile(string input, string search) { try { return File.ReadLines(input).Any(x => x.Contains(search)); } catch (Exception ex) { Console.WriteLine(ex); // 调整顺序,确保异常信息能输出 return false; } } } }
示例ESRI SHP PRJ文件内容
GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
解决方案
只需修改方法参数为关键词列表,通过嵌套LINQ的Any方法实现多关键词检测,同时优化读取逻辑只检测文件开头行提升性能:
using System; using System.IO; using System.Linq; using System.Collections.Generic; namespace TestPgm { public class Check_PRJ { public static void Main() { Console.Write("请输入文件路径及名称:"); string fname = Console.ReadLine(); // 定义ESRI PRJ特征关键词列表 var esriPrjKeywords = new List<string> { "GEOGCS[", "PROJCS[", "GEOCCS[" }; if (IsEsriShpPrjFile(fname, esriPrjKeywords)) Console.WriteLine("该PRJ文件是GIS SHP文件的组成部分,并非损坏文件,请勿删除。"); else Console.WriteLine("该文件是正确的PRJ文件。"); } /// <summary> /// 检测文件是否为ESRI SHP配套的PRJ文件 /// </summary> /// <param name="filePath">文件路径</param> /// <param name="keywords">需要检测的关键词列表</param> /// <returns>是否为ESRI SHP PRJ文件</returns> static bool IsEsriShpPrjFile(string filePath, List<string> keywords) { try { // 只读取文件前5行(可按需调整),避免读取大文件全部内容 return File.ReadLines(filePath).Take(5) .Any(line => keywords.Any(keyword => line.Contains(keyword))); } catch (Exception ex) { Console.WriteLine($"读取文件出错:{ex.Message}"); return false; } } } }
核心修改说明
- 将单个关键词参数改为
List<string>类型的关键词列表,支持多词检测 - 嵌套
Any方法:外层判断是否存在匹配行,内层判断该行是否包含任意目标关键词 - 增加
Take(5)仅读取文件开头5行,针对ESRI PRJ关键词集中在开头的特性优化性能 - 修正原代码中catch块的执行顺序,确保异常信息能正常输出
- 重命名方法为
IsEsriShpPrjFile,语义更清晰
内容的提问来源于stack exchange,提问作者User_zyp9
相关产品推荐
相关产品推荐

