2010-08-10 106 views
1

我需要使用C#搜索名称以ACCESS开头的日志文件的目录(C:\ Logs)。一旦我找到一个以ACCESS开头的文件,我需要搜索该文件并创建一个以Identity =“”开头的字符串集合。例如,Identity =“SWN \ smithj”,因此我需要从Identity到最后一个双引号集。在到达文件末尾之后,我需要转到以ACCESS开头的下一个文件。有人可以告诉我如何在C#中执行此操作吗?以ACCESS开头的文件搜索目录,然后搜索该文件

非常感谢

回答

2

看起来你已经来到这里有两个功能:
1)像访问名查找文件*
2)搜索这些文件,对于喜欢“标识= *”

线

要做到第一个,使用一个DirectoryInfo对象和GetFiles()方法,搜索模式为“ACCESS *”。

DirectoryInfo myDir = new DirectoryInfo(dirPath); 
var files = DirectoryInfo.GetFiles("ACCESS*"); 

然后,您将遍历这些文件寻找您需要的数据。

List<Tuple<string, string>> IdentityLines = new List<Tuple<string, string>>();//Item1 = filename, Item2 = line 
foreach(FileInfo file in files) 
{ 
    using(StreamReader sr = new StreamReader(file.FullName) //double check that file.FullName I don't remember for sure if it's right 
    { 
     while(!string.IsNullOrEmpty(string line = sr.Read()) 
     { 
      if(line.StartsWith("Identity=")) 
       IdentityLines.Add(file.FileName, line); 
     } 
    } 
} 

这没有被编译,所以仔细检查它,但它应该是非常接近你需要的。

编辑:基于来自OP的评论添加了完整的解决方案。已编译并运行。

​​
+0

嗨Allen- 行只是你的循环之前,是正确的?什么是元组,什么是IdentityLines? – Josh 2010-08-10 15:06:21

+0

元组是配对类型。基本上它只是用来创建两段数据之间的相关性。它对于C#4是新手,因此如果使用3.5或更早的版本,可以用List >替换它。 IdentityLines只是我给列表的变量名。一旦你完成了你的线条的收集,你可以将它们与它们被发现的文件一起输出。 – AllenG 2010-08-10 15:09:19

+0

@Allen - 我用List > IdentityLines;在最后一行的while循环中,我有IdentityLines.Add(file.Name,line);我得到了一个“没有超载方法为ADD需要两个参数,想法? – Josh 2010-08-10 15:22:43

2

这是一个非常简洁的方式来完成你所追求的。

public static IEnumerable<string> GetSpecificLines(this DirectoryInfo dir, string fileSearchPattern, Func<string, bool> linePredicate) 
{ 
    FileInfo[] files = dir.GetFiles(fileSearchPattern); 

    return files 
     .SelectMany(f => File.ReadAllLines(f.FullName)) 
     .Where(linePredicate); 
} 

用法:

var lines = new DirectoryInfo("C:\Logs") 
    .GetSpecificLines("ACCESS*", line => line.StartsWith("Identity=")); 
+0

非常好用的linq。我想知道是否将ReadAllLines的Where()过滤器链接起来更高效?例如 .SelectMany(F => File.ReadAllLines(f.FullName)。凡(linePredicate)); 这种方式在过滤之前不会将大量数据存储在缓冲区中。 – Jacob 2010-08-10 16:38:58

+0

@Jacob:我明白你的意思了;但除非我错了,否则确实不应该有任何区别。由于'SelectMany'和'Where'被懒惰地评估,步骤将是相同的:'File.ReadAllLines'返回的每个'string []'数组中的行将单独枚举,只有匹配'linePredicate'被退回。如果你通过调试器中的代码,你会明白我的意思。 – 2010-08-10 16:49:16

+0

@Jacob :(换句话说,我要说的是,你不会在缓冲区中存储“大量数据” - 除了File.ReadAllLines返回的'string []'数组之外',无论如何 - 因为Linq扩展方法提供了懒惰评估。) – 2010-08-10 16:51:01