首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >最好使用C#在所有文件中搜索字符串

最好使用C#在所有文件中搜索字符串
EN

Stack Overflow用户
提问于 2012-12-21 16:15:50
回答 5查看 46.6K关注 0票数 31

在参考了许多博客和文章之后,我已经找到了下面的代码,用于搜索文件夹中所有文件中的字符串。在我的测试中效果很好。

问题

  1. 有更快的方法(使用C#)吗?
  2. 是否有任何情况会导致此代码失败?

注意:我用非常小的文件进行了测试。也很少有文件。

代码语言:javascript
复制
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);
                }
            }

    }

参考

  1. 使用StreamReader检查文件是否包含字符串
  2. 使用两个条件拆分字符串
  3. C#检测路径中的文件夹连接
  4. 检测符号链接、连接点、安装点和硬链接
  5. 带补点的FolderBrowserDialog SelectedPath
  6. C# -图像的高质量字节阵列转换
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-12-21 16:20:38

而不是File.ReadAllText()更好地使用

代码语言:javascript
复制
File.ReadLines(@"C:\file.txt");

它返回IEnumerable (生成),因此如果在到达文本文件的最后一行之前找到了字符串,则不必读取整个文件。

票数 30
EN

Stack Overflow用户

发布于 2012-12-21 16:36:45

我写了一些非常相似的东西,一些我会推荐的修改。

  1. 使用Directory.EnumerateDirectories而不是GetDirectories,它将立即与IEnumerable一起返回,因此您不需要等待它在处理之前完成对所有目录的读取。
  2. 使用ReadLines而不是ReadAllText,这将在内存中一次只加载一行,如果您访问一个大文件,这将是一个很大的问题。
  3. 如果您使用的是新版本的.NET use Parallel.ForEach,这将允许您一次搜索多个文件。
  4. 您可能无法打开该文件,您需要检查您的程序需要管理权限的读取权限或添加到清单中 (仍然应该检查)

我正在创建一个二进制搜索工具,下面是我为帮助您而写的一些片段。

代码语言:javascript
复制
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搜索算法进行很大的改进,但是我找不到二进制实现,而且我没有时间编写它来自己实现它。

票数 11
EN

Stack Overflow用户

发布于 2012-12-21 16:30:03

这里的主要问题是,您正在为每次搜索实时搜索所有文件。如果2+用户同时进行搜索,也有可能发生文件访问冲突。

为了戏剧性地提高性能,我会提前对文件进行索引,并在文件被编辑/保存时对它们进行索引。使用类似于lucene.net的内容存储索引,然后查询索引(同样使用luence.net)并将文件名返回给用户。因此,用户从不直接查询文件。

如果您遵循这个所以波斯特中的链接,您可能在实现索引方面有一个先机。我没有跟踪链接,但值得一看。

只要提醒一下,这将是一个强烈的转变,从你目前的做法,并将需要

  1. 监视/索引文件的服务
  2. UI项目
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13993530

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档