Advertisement
Guest User

Untitled

a guest
May 29th, 2020
530
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.80 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Threading;
  5. using System.IO;
  6.  
  7.  
  8.  
  9. namespace MySearcher
  10. {
  11.     public class Searcher
  12.     {
  13.         // ----- Asynchronous Events -----
  14.  
  15.         public delegate void FoundInfoEventHandler(FoundInfoEventArgs e);
  16.         public static event FoundInfoEventHandler FoundInfo;
  17.  
  18.         public delegate void ThreadEndedEventHandler(ThreadEndedEventArgs e);
  19.         public static event ThreadEndedEventHandler ThreadEnded;
  20.  
  21.  
  22.         // ----- Variables -----
  23.  
  24.         private static Thread m_thread = null;
  25.         private static Boolean m_stop = false;
  26.         private static SearcherParams m_pars = null;
  27.         private static Byte[] m_containingBytes = null;
  28.  
  29.  
  30.         // ----- Public Methods -----
  31.  
  32.         public static Boolean Start(SearcherParams pars)
  33.         {
  34.             Boolean success = false;
  35.  
  36.             if (m_thread == null)
  37.             {
  38.                 // Perform a reset of all variables,
  39.                 // to ensure that the state of the searcher is the same on every new start:
  40.                 ResetVariables();
  41.  
  42.                 // Remember the parameters:
  43.                 m_pars = pars;
  44.  
  45.                 // Start searching for FileSystemInfos that match the parameters:
  46.                 m_thread = new Thread(new ThreadStart(SearchThread));
  47.                 m_thread.Start();
  48.                
  49.                 success = true;
  50.             }
  51.  
  52.             return success;
  53.         }
  54.  
  55.         public static void Stop()
  56.         {
  57.             // Stop the thread by setting a flag:
  58.             m_stop = true;
  59.         }
  60.  
  61.  
  62.         // ----- Private Methods -----
  63.  
  64.         private static void ResetVariables()
  65.         {
  66.             m_thread = null;
  67.             m_stop = false;
  68.             m_pars = null;
  69.             m_containingBytes = null;
  70.         }
  71.  
  72.         private static void SearchThread()
  73.         {
  74.             Boolean success = true;
  75.             String errorMsg = "";
  76.  
  77.             // Search for FileSystemInfos that match the parameters:
  78.             if ((m_pars.SearchDir.Length >= 3) && (Directory.Exists(m_pars.SearchDir)))
  79.             {
  80.                 if (m_pars.FileNames.Count > 0)
  81.                 {
  82.                     // Convert the string to search for into bytes if necessary:
  83.                     if (m_pars.ContainingChecked)
  84.                     {
  85.                         if (m_pars.ContainingText != "")
  86.                         {
  87.                             try
  88.                             {
  89.                                 m_containingBytes = m_pars.Encoding.GetBytes(m_pars.ContainingText);
  90.                             }
  91.                             catch (Exception)
  92.                             {
  93.                                 success = false;
  94.                                 errorMsg = "The string\r\n" + m_pars.ContainingText + "\r\ncannot be converted into bytes.";
  95.                             }
  96.                         }
  97.                         else
  98.                         {
  99.                             success = false;
  100.                             errorMsg = "The string to search for must not be empty.";
  101.                         }
  102.                     }
  103.  
  104.                     if (success)
  105.                     {
  106.                         // Get the directory info for the search directory:
  107.                         DirectoryInfo dirInfo = null;
  108.                         try
  109.                         {
  110.                             dirInfo = new DirectoryInfo(m_pars.SearchDir);
  111.                         }
  112.                         catch (Exception ex)
  113.                         {
  114.                             success = false;
  115.                             errorMsg = ex.Message;
  116.                         }
  117.  
  118.                         if (success)
  119.                         {
  120.                             // Search the directory (maybe recursively),
  121.                             // and raise events if something was found:
  122.                             SearchDirectory(dirInfo);
  123.                         }
  124.                     }
  125.                 }
  126.                 else
  127.                 {
  128.                     success = false;
  129.                     errorMsg = "Please enter one or more filenames to search for.";
  130.                 }
  131.             }
  132.             else
  133.             {
  134.                 success = false;
  135.                 errorMsg = "The directory\r\n" + m_pars.SearchDir + "\r\ndoes not exist.";
  136.             }
  137.  
  138.             // Remember the thread has ended:
  139.             m_thread = null;
  140.  
  141.             // Raise an event:
  142.             if (ThreadEnded != null)
  143.             {
  144.                 ThreadEnded(new ThreadEndedEventArgs(success, errorMsg));
  145.             }
  146.         }
  147.  
  148.         private static void SearchDirectory(DirectoryInfo dirInfo)
  149.         {
  150.             if (!m_stop)
  151.             {
  152.                 try
  153.                 {
  154.                     foreach (String fileName in m_pars.FileNames)
  155.                     {
  156.                         FileSystemInfo[] infos = dirInfo.GetFileSystemInfos(fileName);
  157.  
  158.                         foreach (FileSystemInfo info in infos)
  159.                         {
  160.                             if (m_stop)
  161.                             {
  162.                                 break;
  163.                             }
  164.  
  165.                             if (MatchesRestrictions(info))
  166.                             {
  167.                                 // We have found a matching FileSystemInfo, so let's raise an event:
  168.                                 if (FoundInfo != null)
  169.                                 {
  170.                                     FoundInfo(new FoundInfoEventArgs(info));
  171.                                 }
  172.                             }
  173.                         }
  174.                     }
  175.  
  176.                     if (m_pars.IncludeSubDirsChecked)
  177.                     {
  178.                         DirectoryInfo[] subDirInfos = dirInfo.GetDirectories();
  179.                         foreach (DirectoryInfo subDirInfo in subDirInfos)
  180.                         {
  181.                             if (m_stop)
  182.                             {
  183.                                 break;
  184.                             }
  185.  
  186.                             // Recursion:
  187.                             SearchDirectory(subDirInfo);
  188.                         }
  189.                     }
  190.                 }
  191.                 catch (Exception)
  192.                 {
  193.                 }
  194.             }
  195.         }
  196.  
  197.         private static Boolean MatchesRestrictions(FileSystemInfo info)
  198.         {
  199.             Boolean matches = true;
  200.  
  201.             if (matches && m_pars.NewerThanChecked)
  202.             {
  203.                 matches = (info.LastWriteTime >= m_pars.NewerThanDateTime);
  204.             }
  205.  
  206.             if (matches && m_pars.OlderThanChecked)
  207.             {
  208.                 matches = (info.LastWriteTime <= m_pars.OlderThanDateTime);
  209.             }
  210.  
  211.             if (matches && m_pars.ContainingChecked)
  212.             {
  213.                 matches = false;
  214.                 if (info is FileInfo)
  215.                 {
  216.                     matches = FileContainsBytes(info.FullName, m_containingBytes);
  217.                 }
  218.             }
  219.  
  220.             return matches;
  221.         }
  222.  
  223.         private static Boolean FileContainsBytes(String path, Byte[] compare)
  224.         {
  225.             Boolean contains = false;
  226.  
  227.             Int32 blockSize = 4096;
  228.             if ((compare.Length >= 1) && (compare.Length <= blockSize))
  229.             {
  230.                 Byte[] block = new Byte[compare.Length - 1 + blockSize];
  231.  
  232.                 try
  233.                 {
  234.                     FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
  235.  
  236.                     // Read the first bytes from the file into "block":
  237.                     Int32 bytesRead = fs.Read(block, 0, block.Length);
  238.  
  239.                     do
  240.                     {
  241.                         // Search "block" for the sequence "compare":
  242.                         Int32 endPos = bytesRead - compare.Length + 1;
  243.                         for (Int32 i = 0; i < endPos; i++)
  244.                         {
  245.                             // Read "compare.Length" bytes at position "i" from the buffer,
  246.                             // and compare them with "compare":
  247.                             Int32 j;
  248.                             for (j = 0; j < compare.Length; j++)
  249.                             {
  250.                                 if (block[i + j] != compare[j])
  251.                                 {
  252.                                     break;
  253.                                 }
  254.                             }
  255.  
  256.                             if (j == compare.Length)
  257.                             {
  258.                                 // "block" contains the sequence "compare":
  259.                                 contains = true;
  260.                                 break;
  261.                             }
  262.                         }
  263.  
  264.                         // Search completed?
  265.                         if (contains || (fs.Position >= fs.Length))
  266.                         {
  267.                             break;
  268.                         }
  269.                         else
  270.                         {
  271.                             // Copy the last "compare.Length - 1" bytes to the beginning of "block":
  272.                             for (Int32 i = 0; i < (compare.Length - 1); i++)
  273.                             {
  274.                                 block[i] = block[blockSize + i];
  275.                             }
  276.  
  277.                             // Read the next "blockSize" bytes into "block":
  278.                             bytesRead = compare.Length - 1 + fs.Read(block, compare.Length - 1, blockSize);
  279.                         }
  280.                     }
  281.                     while (!m_stop);
  282.  
  283.                     fs.Close();
  284.                 }
  285.                 catch (Exception)
  286.                 {
  287.                 }
  288.             }
  289.  
  290.             return contains;
  291.         }
  292.     }
  293. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement