• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C#代码搜索器WEBUS2.0InAction-[源代码]-C#代码搜索器

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

WEBUS2.0 In Action - [源代码] - C#代码搜索器

最近由于工作的需要, 要分析大量C#代码, 在数万个cs文件中搜索特定关键词. 这是一项非常耗时的工作, 用Notepad++要运行接近半个小时. 于是我利用WEBUS2.0 SDK创建了一个代码搜索器程序, 非常方便的完成了这项工作.

Code Search程序首先会在选定的目录中搜索所有cs文件:

    private void btnOpen_Click(object sender, EventArgs e)
        {
            try
            {
                if (folderBrowserDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    Task.Factory.StartNew(IndexProc);
                    //...
        }

然后创建IIndexer, 并在一个线程中为所有找到的文件编制索引:

        void IndexProc()
        {
            var files = Directory.GetFiles(folderBrowserDialog1.SelectedPath, "*.cs", SearchOption.AllDirectories);
            if (files != null && files.Length > 0)
            {
                //...this.ResetIndex();
                foreach (var file in files)
                {
                    Document doc = new Document();
                    doc.Fields.Add(new Field("FileName", file, FieldAttributes.None));
                    doc.Fields.Add(new Field("Code", StringHelper.LoadString(file), FieldAttributes.AnalyseIndex));
                    m_Index.Add(doc);
                    //...
                }
            }
            //...
        }

        void ResetIndex()
        {
            if (m_Index != null)
            {
                m_Index.Close();
            }
            m_Index = new IndexManager(new CodeAnalyzer());
            m_Index.DumpDocs = 3000;
            m_Index.DumpSize = 10;
            m_Index.MinIndexSize = int.MaxValue;
            m_Index.MaxIndexSize = int.MaxValue;
            m_Index.MergeFactor = int.MaxValue;
            m_Index.New(AppDomain.CurrentDomain.BaseDirectory + @"\Index");
            m_Searcher = new IndexSearcher(m_Index);
        }

通过调节DumpDocs和DumpSize, 可以优化程序的内存占用;

通过调节Min/MaxIndexSize和MergeFactor, 可以优化程序的IO性能, 目前我设置的MinIndexSize最大意味着自始至终只会生成一个索引片段; MergeFactor最大意味着从不合并索引片段.

在创建索引的时候, 我们使用的是专门为代码分析设计的IAnalyzer:

    class CodeAnalyzer : IAnalyzer
    {
        //...public ITokenStream GetTokenStream(Webus.Documents.Field field)
        {
            if (field.Name == "Code")
            {
                return this.GetTokenStream(field.Value.ToString());
            }
            else
            {
                return null;
            }
        }
    }

    class CodeTokenStream : ITokenStream
    {
        HashSet<string> stops = new HashSet<string>(new string[] { 
            "abstract",
            "event",    
            "new",    
            //... 
            "enum",    
            "namespace",    
            "string"
        });
        Queue<Token> m_Buffer = new Queue<Token>();
        public CodeTokenStream(string text)
        {
            MatchCollection mc = Regex.Matches(text, @"\w+");
            foreach (Match m in mc)
            {
                var key = m.Value.ToLower();
                if (stops.Contains(key) == false)
                {
                    m_Buffer.Enqueue(new Token(key, m.Index, m.Length));
                }
            }
        }
        //...
}

这个分析器中包含了所有C#的关键词, 由于他们是绝对高频词并且没有搜索的意义, 因此在分析的时候会跳过这些词汇而不做任何处理. 

在编制索引的时候通过事件将状态更新到UI上面:

        private void frmCodeSearch_Load(object sender, EventArgs e)
        {
            try
            {
                this.StatusChanged += new StatusChangeEventHandler(frmCodeSearch_StatusChanged);
                //...
        }

        delegate void UpdateUI();
        void frmCodeSearch_StatusChanged(object sender, string status)
        {
            this.Invoke(new UpdateUI(() => { this.txtStatus.Text = status; }));
        }

这里是跨线程更新UI, 因此需要使用this.Invoke来封送相应操作. 

索引编制过程中就可以开始搜索了:

对应代码如下:

        private void txtKeyword_TextChanged(object sender, EventArgs e)
        {
            try
            {
                TermQuery query = new TermQuery(new Term("Code", txtKeyword.Text.ToLower()));
                var hits = m_Searcher.Search(query);
                List<SearchResult> result = new List<SearchResult>();
                foreach (HitDoc hit in hits)
                {
                    StandardHighlighter hl = new StandardHighlighter(hit);
                    result.Add(new SearchResult(hit));
                }
                dgvResult.DataSource = result;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ExceptionHelper.ToString(ex));
            }
        }

创建一个TermQuery对象, 对Code字段进行搜索, 构建List<SearchResult>类型的结果集, 并且绑定到DataGridView上面, 大功告成! enjoy~!

下载源代码

阅读更多WEBUS2.0 SDK文章

 

 
 
WEBUS
WEBUS

最近由于工作的需要, 要分析大量C#代码, 在数万个cs文件中搜索特定关键词. 这是一项非常耗时的工作, 用Notepad++要运行接近半个小时. 于是我利用WEBUS2.0 SDK创建了一个代码搜索器程序, 非常方便的完成了这项工作.

Code Search程序首先会在选定的目录中搜索所有cs文件:

    private void btnOpen_Click(object sender, EventArgs e)
        {
            try
            {
                if (folderBrowserDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    Task.Factory.StartNew(IndexProc);
                    //...
        }

然后创建IIndexer, 并在一个线程中为所有找到的文件编制索引:

        void IndexProc()
        {
            var files = Directory.GetFiles(folderBrowserDialog1.SelectedPath, "*.cs", SearchOption.AllDirectories);
            if (files != null && files.Length > 0)
            {
                //...this.ResetIndex();
                foreach (var file in files)
                {
                    Document doc = new Document();
                    doc.Fields.Add(new Field("FileName", file, FieldAttributes.None));
                    doc.Fields.Add(new Field("Code", StringHelper.LoadString(file), FieldAttributes.AnalyseIndex));
                    m_Index.Add(doc);
                    //...
                }
            }
            //...
        }

        void ResetIndex()
        {
            if (m_Index != null)
            {
                m_Index.Close();
            }
            m_Index = new IndexManager(new CodeAnalyzer());
            m_Index.DumpDocs = 3000;
            m_Index.DumpSize = 10;
            m_Index.MinIndexSize = int.MaxValue;
            m_Index.MaxIndexSize = int.MaxValue;
            m_Index.MergeFactor = int.MaxValue;
            m_Index.New(AppDomain.CurrentDomain.BaseDirectory + @"\Index");
            m_Searcher = new IndexSearcher(m_Index);
        }

通过调节DumpDocs和DumpSize, 可以优化程序的内存占用;

通过调节Min/MaxIndexSize和MergeFactor, 可以优化程序的IO性能, 目前我设置的MinIndexSize最大意味着自始至终只会生成一个索引片段; MergeFactor最大意味着从不合并索引片段.

在创建索引的时候, 我们使用的是专门为代码分析设计的IAnalyzer:

    class CodeAnalyzer : IAnalyzer
    {
        //...public ITokenStream GetTokenStream(Webus.Documents.Field field)
        {
            if (field.Name == "Code")
            {
                return this.GetTokenStream(field.Value.ToString());
            }
            else
            {
                return null;
            }
        }
    }

    class CodeTokenStream : ITokenStream
    {
        HashSet<string> stops = new HashSet<string>(new string[] { 
            "abstract",
            "event",    
            "new",    
            //... 
            "enum",    
            "namespace",    
            "string"
        });
        Queue<Token> m_Buffer = new Queue<Token>();
        public CodeTokenStream(string text)
        {
            MatchCollection mc = Regex.Matches(text, @"\w+");
            foreach (Match m in mc)
            {
                var key = m.Value.ToLower();
                if (stops.Contains(key) == false)
                {
                    m_Buffer.Enqueue(new Token(key, m.Index, m.Length));
                }
            }
        }
        //...
}

这个分析器中包含了所有C#的关键词, 由于他们是绝对高频词并且没有搜索的意义, 因此在分析的时候会跳过这些词汇而不做任何处理. 

在编制索引的时候通过事件将状态更新到UI上面:

        private void frmCodeSearch_Load(object sender, EventArgs e)
        {
            try
            {
                this.StatusChanged += new StatusChangeEventHandler(frmCodeSearch_StatusChanged);
                //...
        }

        delegate void UpdateUI();
        void frmCodeSearch_StatusChanged(object sender, string status)
        {
            this.Invoke(new UpdateUI(() => { this.txtStatus.Text = status; }));
        }

这里是跨线程更新UI, 因此需要使用this.Invoke来封送相应操作. 

索引编制过程中就可以开始搜索了:

对应代码如下:

        private void txtKeyword_TextChanged(object sender, EventArgs e)
        {
            try
            {
                TermQuery query = new TermQuery(new Term("Code", txtKeyword.Text.ToLower()));
                var hits = m_Searcher.Search(query);
                List<SearchResult> result = new List<SearchResult>();
                foreach (HitDoc hit in hits)
                {
                    StandardHighlighter hl = new StandardHighlighter(hit);
                    result.Add(new SearchResult(hit));
                }
                dgvResult.DataSource = result;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ExceptionHelper.ToString(ex));
            }
        }

创建一个TermQuery对象, 对Code字段进行搜索, 构建List<SearchResult>类型的结果集, 并且绑定到DataGridView上面, 大功告成! enjoy~!

下载源代码

阅读更多WEBUS2.0 SDK文章

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap