Shmuel Naukarkar
Shmuel Naukarkar

Reputation: 263

Why when searching for a string in a file it's not finding it?

I did a simple program that will search in a specific files types fro a strings but it's not finding it.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Runtime.InteropServices;

namespace Search_Text_In_Files
{
    public partial class Form1 : Form
    {
        StreamWriter w = new StreamWriter(@"e:\textresults.txt");

        public Form1()
        {
            InitializeComponent();

            backgroundWorker1.RunWorkerAsync();
        }

        bool result = false;
        public List<string> FindLines(string DirName, string TextToSearch)
        {
            int counter = 0;
            List<string> findLines = new List<string>();
            DirectoryInfo di = new DirectoryInfo(DirName);

            List<FileInfo> l = new List<FileInfo>();
            CountFiles(di, l);

            int totalFiles = l.Count;
            int countFiles = 0;
            if (di != null && di.Exists)
            {
                if (CheckFileForAccess(DirName) == true)
                {
                    foreach (FileInfo fi in l)
                    {
                        backgroundWorker1.ReportProgress((int)((double)countFiles / totalFiles * 100.0), fi.Name);
                        countFiles++;
                        System.Threading.Thread.Sleep(1);

                        if (string.Compare(fi.Extension, ".cs", true) == 0)
                        {
                            using (StreamReader sr = fi.OpenText())
                            {
                                string s = "";
                                while ((s = sr.ReadLine()) != null)
                                {
                                    if (s.Contains(TextToSearch))
                                    {
                                        counter++;
                                        findLines.Add(s);
                                        result = true;
                                        backgroundWorker1.ReportProgress(0, fi.FullName);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return findLines;
        }

        private void CountFiles(DirectoryInfo di, List<FileInfo> l)
        {
            try
            {
                l.AddRange(di.EnumerateFiles());
            }
            catch
            {

            }

            try
            {
                IEnumerable<DirectoryInfo> subDirs = di.EnumerateDirectories();
                if (subDirs.Count() > 0)
                {
                    foreach (DirectoryInfo dir in subDirs)
                        CountFiles(dir, l);
                }
            }
            catch 
            {
                string err = "";
            }
        }

        private bool CheckForAccess(string PathName)
        {
            if (File.Exists(PathName) == true)
                return CheckFileForAccess(PathName);

            if (Directory.Exists(PathName) == true)
                return CheckFolderForAccess(PathName);

            return false;
        }


        private bool CheckFileForAccess(string FileName)
        {
            FileSecurity fs = new FileSecurity(FileName, AccessControlSections.Access);
            if (fs == null)
                return false;

            AuthorizationRuleCollection TheseRules = fs.GetAccessRules(true, true, typeof(NTAccount));
            if (TheseRules == null)
                return false;

            return CheckACL(TheseRules);
        }

        private bool CheckFolderForAccess(string FolderName)
        {
            DirectoryInfo di = new DirectoryInfo(FolderName);
            if (di == null)
                return false;

            DirectorySecurity acl = di.GetAccessControl(AccessControlSections.Access);
            if (acl == null)
                return false;

            AuthorizationRuleCollection TheseRules = acl.GetAccessRules(true, true, typeof(NTAccount));
            if (TheseRules == null)
                return false;

            return CheckACL(TheseRules);
        }

        private bool CheckACL(AuthorizationRuleCollection TheseRules)
        {
            foreach (FileSystemAccessRule ThisRule in TheseRules)
            {
                if ((ThisRule.FileSystemRights & FileSystemRights.Read) == FileSystemRights.Read)
                {
                    if (ThisRule.AccessControlType == AccessControlType.Deny)
                        return false;
                }

            }

            return true;
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            FindLines(@"d:\c-sharp", "FileShellExtension");
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
            label2.Text = e.UserState.ToString();
            if (result == true)
            {
                listView1.Items.Add(e.UserState.ToString());
                result = false;
            }
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled == true)
            {

            }
            else if (e.Error != null)
            {

            }
            else
            {

            }
        }
    }
}

In this case i'm looking for the string "FileShellExtension" in the directory d:\c-sharp and only in files ending with cs for example form1.cs

And the only result i'm getting is in this program it's finding the line as result since the string "FileShellExtension" is exist here.

FindLines(@"d:\c-sharp", "FileShellExtension");

In another project i have the string "FileShellExtension" in a form1 like this:

NameSpace FileShellExtension

But it did not find it.

What i want it to do first to pass over the result of the string being found in this program the searching program it should not be a result.

Second why it didn't find the string as part of the: NameSpace FileShellExtension ?

Upvotes: 0

Views: 75

Answers (1)

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186803

I suggest changing current FindLines signature into

public static IEnumerable<String> FindLines(String dirName, String textToSearch) {
  if (null == dirName)
    throw new ArgumentNullException("dirName");
  else if (null == textToSearch)
    throw new ArgumentNullException("textToSearch");

  //TODO: put a right mask instead of *.txt  
  var files = Directory
    .EnumerateFiles(dirName, "*.txt", SearchOption.AllDirectories)
    .Where(file => true); //TODO: put right condition on file (now all accepted)  

  return files
    .SelectMany(file => File.ReadLines(file))
    .Where(line => line.Contains(textToSearch));
}

Then (when you've debugged the routine) you can materialize the result while adding a background worker or whatever:

public static List<String> FindLinesToList(String dirName, String textToSearch) {
  List<String> result = new List<String>();

  foreach (var item in FindLines(dirName, textToSearch)) {
    backgroundWorker1.ReportProgress(...)
    countFiles++;  

    ...   

    result.Add(item);
  }
}

It's far easier to debug, e.g. you can change

var files = Directory
...

into

var files = new String[@"C:\MyFile.txt"]; 

and test if search in the file is correct.

Upvotes: 2

Related Questions