2016-03-11 54 views
0

我做了一個簡單的程序,它將搜索特定文件類型的字符串,但它沒有找到它。爲什麼在文件中搜索字符串時找不到它?

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 
      { 

      } 
     } 
    } 
} 

在這種情況下,我正在尋找在目錄d字符串「FileShellExtension」:\ C-尖銳,只有在與CS例如結尾的文件Form1.cs的

而唯一的結果,我因爲字符串「FileShellExtension」在此處存在,所以在該程序中它正在查找結果行。

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

在另一個項目中,我有一個form1的字符串 「FileShellExtension」 是這樣的:

NameSpace FileShellExtension 

但它並沒有找到它。

我希望它首先傳遞在此程序中找到的字符串的結果搜索程序,它不應該是結果。

第二個爲什麼它沒有找到字符串作爲其中的一部分:NameSpace FileShellExtension?

回答

2

我建議改變當前FindLines簽名改成

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)); 
} 

然後(當你調試的程序),您可以物化的結果,同時增加了後臺工作或什麼:

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); 
    } 
} 

這是遠更容易調試,例如你可以改變

var files = Directory 
... 

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

和測試,如果在文件中搜索是否正確。