在参考了很多博客和文章后,我已经达到了以下代码,用于在文件夹内的所有文件中搜索字符串。它在我的测试中运行良好。
问题
注意:我使用非常小的文件进行了测试。文件数量也很少。
CODE
static void Main()
{
string sourceFolder = @"C:\Test";
string searchWord = ".class1";
List<string> allFiles = new List<string>();
AddFileNamesToList(sourceFolder, allFiles);
foreach (string fileName in allFiles)
{
string contents = File.ReadAllText(fileName);
if (contents.Contains(searchWord))
{
Console.WriteLine(fileName);
}
}
Console.WriteLine(" ");
System.Console.ReadKey();
}
public static void AddFileNamesToList(string sourceDir, List<string> allFiles)
{
string[] fileEntries = Directory.GetFiles(sourceDir);
foreach (string fileName in fileEntries)
{
allFiles.Add(fileName);
}
//Recursion
string[] subdirectoryEntries = Directory.GetDirectories(sourceDir);
foreach (string item in subdirectoryEntries)
{
// Avoid "reparse points"
if ((File.GetAttributes(item) & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint)
{
AddFileNamesToList(item, allFiles);
}
}
}
参考
答案 0 :(得分:26)
而不是File.ReadAllText()更好地使用
File.ReadLines(@"C:\file.txt");
返回IEnumerable
(已产生),因此如果在到达文本文件的最后一行之前找到了字符串,则不必读取整个文件
答案 1 :(得分:10)
我写的东西非常相似,我建议做一些改变。
我正在创建一个二进制搜索工具,这里有一些我写给你的手的片段
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Parallel.ForEach(Directory.EnumerateFiles(_folder, _filter, SearchOption.AllDirectories), Search);
}
//_array contains the binary pattern I am searching for.
private void Search(string filePath)
{
if (Contains(filePath, _array))
{
//filePath points at a match.
}
}
private static bool Contains(string path, byte[] search)
{
//I am doing ReadAllBytes due to the fact that I am doing a binary search not a text search
// There are no "Lines" to seperate out on.
var file = File.ReadAllBytes(path);
var result = Parallel.For(0, file.Length - search.Length, (i, loopState) =>
{
if (file[i] == search[0])
{
byte[] localCache = new byte[search.Length];
Array.Copy(file, i, localCache, 0, search.Length);
if (Enumerable.SequenceEqual(localCache, search))
loopState.Stop();
}
});
return result.IsCompleted == false;
}
这使用两个嵌套的并行循环。这种设计非常低效,使用Booyer-Moore search algorithm可以大大改善,但是我找不到二进制实现,而且我最初没有时间编写它来实现它。
答案 2 :(得分:3)
这里的主要问题是您每次搜索都会实时搜索所有文件。如果有2个以上的用户同时搜索,则还存在文件访问冲突的可能性。
以极大地提高性能我会提前索引文件,并在编辑/保存时对其进行索引。使用类似lucene.net的内容存储索引,然后查询索引(再次使用luence.net)并将文件名返回给用户。所以用户永远不会直接查询文件。
如果您按照此SO Post中的链接进行操作,则可能需要先实施索引。我没有按照链接,但值得一看。
只是抬头,这将是你当前方法的一个强烈转变,需要
答案 3 :(得分:1)
如果您缺少permission to open a file
,我认为您的代码会失败并出现异常。
将其与此处的代码进行比较:http://bgrep.codeplex.com/releases/view/36186
后一个代码支持
- 你应该考虑的事情。
答案 4 :(得分:1)
而不是Contains
更好地使用算法Boyer-Moore搜索。
失败场景:文件没有读取权限。