none
comparing a directory of files to another file outside the directory using hash RRS feed

  • Question

  • Hi all, 

    I have created a win form where I select the directory to loop through and the external file to compare those files.

    When I select the external file using filebrowser I read the file as a hash. Later when I select the folder of files to loop through I also read these as a hash. The Problem I am having is in passing the external file hash to the function that compares them.

    Here is my code so far;

    public partial class Form1 : Form
    	{
    		List<string> fileNames = new List<string>();
    
    		public Form1()
    		{
    			InitializeComponent();
    		}
    
    		private void btnBrowse_Click(object sender, EventArgs e)
    		{
    			OpenFolder();
    		}
    
    		private void OpenFolder()
    		{
    			if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
    			{
    				string dirName = folderBrowserDialog1.SelectedPath;
    				string simpleFolderName = Path.GetFileNameWithoutExtension(folderBrowserDialog1.SelectedPath);
    				groupBox1.Text = simpleFolderName;
    			}
    		}
    
    		private void btnBrowseFile_Click(object sender, EventArgs e)
    		{
    			string PgiFile = openFileDialog1.FileName;
    			string simpleFileName = Path.GetFileNameWithoutExtension(openFileDialog1.FileName);
    			var hash = HashAlgorithm.Create();
    			var stream = new System.IO.FileStream(PgiFile, System.IO.FileMode.Open);
    			byte[] hashByte_1 = hash.ComputeHash(stream);
    			stream.Close();
    		}
    
    		private void btnStart_Click(object sender, EventArgs e)
    		{
    			string dirName = folderBrowserDialog1.SelectedPath;
    			DirectoryInfo dirInfo = new DirectoryInfo(dirName);
    			foreach (FileInfo StoredProc in dirInfo.GetFiles())
    			{
    				if (!fileNames.Contains(StoredProc.Name))
    				{
    					if (FileIsWanted(StoredProc.Name))
    					{
    						ProcessTheFile(StoredProc);
    
    					}
    				}
    			}
    		}
    
    		private bool FileIsWanted(string pFile)
    		{
    			if (pFile.StartsWith("SP") && (pFile.EndsWith(".txt", StringComparison.InvariantCultureIgnoreCase)))
    			{
    				string fileName = CaptureFilePath(pFile);
    				fileNames.Add(pFile);
    				return true;
    			}
    
    			return false;
    		}
    
    		public void ProcessTheFile(FileInfo pFile)
    		{
    			string simpleFileName = Path.GetFileNameWithoutExtension(pFile.Name);
    			listBox1.Items.Add("Comparing: " + " " + simpleFileName + " " + "with" + " " + "PgiFile Stored Procedure");
    
    			var hash = HashAlgorithm.Create();
    			var stream = new FileStream(pFile.Name, FileMode.Open);
    			byte[] hashByte_2 = hash.ComputeHash(stream);
    			stream.Close();
    
    			if (BitConverter.ToString(hashByte_1) == BitConverter.ToString(hashByte_2))
    
    				listBox1.Items.Add("Equal");
    			else
    				listBox1.Items.Add("Not Equal");
    
    		}
    
    		private string CaptureFilePath(string pFile)
    		{
    			return Path.GetFileNameWithoutExtension(pFile);
    		}		
    	}


    CuriousCoder




    Wednesday, October 25, 2017 11:50 AM

Answers

  • Untested code.

    private string _selectedFile;
    private string _selectedFolder;
    
    private void OpenFolder()
    {
       if (folderBrowserDialog1.ShowDialog() != DialogResult.OK)
          return;
    
       _selectedFolder = folderBrowserDialog1.SelectedPath;
       groupBox1.Text = _selectedFolder;
    }
    
    //Not really sure what this handler does in relation to the selected folder
    private void btnBrowseFile_Click(object sender, EventArgs e)
    {
       if (!String.IsNullOrEmpty(_selectedFile))
          openFileDialog1.FileName = _selectedFile;
    
       if (openFileDialog1.ShowDialog() != DialogResult.OK)
          return;
    
       _selectedFile = openFileDialog1.FileName;
    }
    
    //Promoting the hash algorithm to a field so we create
    //it once
    private readonly HashAlgorithm _hashAlgorithm = HashAlgorithm.Create();
    
    private byte[] GetFileHash ( string filename )
    {
       using (var stream = File.OpenRead(filename))
       {
          return _hashAlgorithm.ComputeHash(stream);
       };
    }
    
    private void btnStart_Click(object sender, EventArgs e)
    {
       var selectedHash = GetFileHash(_selectedFile);
    
       //Unclear what files you're looking for so this code
       //searches the selected folder recursively for all files
       //that start with SP and have a .txt file extension, this
       //eliminates the need for your FileIsWanted method but I
       //left it in in case you need to do additional filtering
       var files = from f in Directory.EnumerateFiles(_selectedFolder, "sp*.txt", SearchOption.AllDirectories)
                   where FileIsWanted(f)
                   select f;
    
       foreach (var file in files)
          ProcessTheFile(file, selectedHash);
    }
    
    private bool FileIsWanted(string pFile)
    {
       //Logical already handled by EnumerateFiles
       return true;
    }
    
    public void ProcessTheFile(string pFile, byte[] targetHash )
    {
       string simpleFileName = Path.GetFileNameWithoutExtension(pFile);
       listBox1.Items.Add("Comparing: " + " " + simpleFileName + " " + "with" + " " + "PgiFile Stored Procedure");
    
       var fileHash = GetFileHash(pFile);
       if (BitConverter.ToString(targetHash) == BitConverter.ToString(fileHash))
          listBox1.Items.Add("Equal");
       else
          listBox1.Items.Add("Not Equal");
    }
    	


    Michael Taylor http://www.michaeltaylorp3.net

    Wednesday, October 25, 2017 5:50 PM
    Moderator

All replies

  • If you need to store data between 2 method calls then either use parameters (if one method calls the other) or store the value(s) you need to persist in a field. The other method can then reference the field.

    In your case though I would simply reorganize my code to store the name of the file to compare against in a field. When you start the comparison process, calculate the hash at that point. Then you can pass the hash to your ProcessTheFile method as a parameter.


    Michael Taylor http://www.michaeltaylorp3.net

    Wednesday, October 25, 2017 1:52 PM
    Moderator
  • Thanks CoolDadTx, 

    What you are saying makes sense but I am struggling to visualise what you said in the code. Could you possibly show an example, please...


    CuriousCoder

    Wednesday, October 25, 2017 3:43 PM
  • Untested code.

    private string _selectedFile;
    private string _selectedFolder;
    
    private void OpenFolder()
    {
       if (folderBrowserDialog1.ShowDialog() != DialogResult.OK)
          return;
    
       _selectedFolder = folderBrowserDialog1.SelectedPath;
       groupBox1.Text = _selectedFolder;
    }
    
    //Not really sure what this handler does in relation to the selected folder
    private void btnBrowseFile_Click(object sender, EventArgs e)
    {
       if (!String.IsNullOrEmpty(_selectedFile))
          openFileDialog1.FileName = _selectedFile;
    
       if (openFileDialog1.ShowDialog() != DialogResult.OK)
          return;
    
       _selectedFile = openFileDialog1.FileName;
    }
    
    //Promoting the hash algorithm to a field so we create
    //it once
    private readonly HashAlgorithm _hashAlgorithm = HashAlgorithm.Create();
    
    private byte[] GetFileHash ( string filename )
    {
       using (var stream = File.OpenRead(filename))
       {
          return _hashAlgorithm.ComputeHash(stream);
       };
    }
    
    private void btnStart_Click(object sender, EventArgs e)
    {
       var selectedHash = GetFileHash(_selectedFile);
    
       //Unclear what files you're looking for so this code
       //searches the selected folder recursively for all files
       //that start with SP and have a .txt file extension, this
       //eliminates the need for your FileIsWanted method but I
       //left it in in case you need to do additional filtering
       var files = from f in Directory.EnumerateFiles(_selectedFolder, "sp*.txt", SearchOption.AllDirectories)
                   where FileIsWanted(f)
                   select f;
    
       foreach (var file in files)
          ProcessTheFile(file, selectedHash);
    }
    
    private bool FileIsWanted(string pFile)
    {
       //Logical already handled by EnumerateFiles
       return true;
    }
    
    public void ProcessTheFile(string pFile, byte[] targetHash )
    {
       string simpleFileName = Path.GetFileNameWithoutExtension(pFile);
       listBox1.Items.Add("Comparing: " + " " + simpleFileName + " " + "with" + " " + "PgiFile Stored Procedure");
    
       var fileHash = GetFileHash(pFile);
       if (BitConverter.ToString(targetHash) == BitConverter.ToString(fileHash))
          listBox1.Items.Add("Equal");
       else
          listBox1.Items.Add("Not Equal");
    }
    	


    Michael Taylor http://www.michaeltaylorp3.net

    Wednesday, October 25, 2017 5:50 PM
    Moderator
  • Thanks for the example,

    I have taken on board what you have shown and modified the example to my code like so;

    	public string _selectedFile;
    		public string _selectedFolder;
    		public string _simpleFilePath;
    
    		public Form1()
    		{
    			InitializeComponent();
    		}
    
    		private void btnBrowse_Click(object sender, EventArgs e)
    		{
    			OpenFolder();
    		}
    
    		private void OpenFolder()
    		{
    			if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
    			{
    				_selectedFolder = folderBrowserDialog1.SelectedPath;
    				string simpleFolderName = Path.GetFileNameWithoutExtension(folderBrowserDialog1.SelectedPath);
    				groupBox1.Text = simpleFolderName;
    				Debug.WriteLine("folder is loaded" + "	" +_selectedFolder);
    			}
    		}
    
    		private void btnBrowseFile_Click(object sender, EventArgs e)
    		{
    			if (!String.IsNullOrEmpty(_selectedFile))
    				openFileDialog1.FileName = _selectedFile;
    
    			if (openFileDialog1.ShowDialog() != DialogResult.OK)
    				return;
    
    			_selectedFile = openFileDialog1.FileName;
    			_simpleFilePath = Path.GetFileNameWithoutExtension(openFileDialog1.FileName);
    			Debug.WriteLine("file is loaded" + "	" +_selectedFile);
    		}
    
    		private void btnStart_Click(object sender, EventArgs e)
    		{
    			string dirName = folderBrowserDialog1.SelectedPath;
    			DirectoryInfo dirInfo = new DirectoryInfo(dirName);
    			listBox1.Items.Add("Comparing to PgiFile Stored Procedure: ");
    			foreach (FileInfo StoredProc in dirInfo.GetFiles())
    			{
    				var selectedHash = GetFileHash(_selectedFile);
    				if (FileIsWanted(StoredProc.Name))
    				{
    					ProcessTheFile(StoredProc.Name, selectedHash);
    				}
    			}
    		}
    
    		private bool FileIsWanted(string pFile)
    		{
    			if (pFile.StartsWith("SP") && (pFile.EndsWith(".txt", StringComparison.InvariantCultureIgnoreCase)))
    			{
    				return true;
    			}
    			return false;
    		}
    
    		public void ProcessTheFile(string pFile, byte[] targetHash)
    		{
    			string simpleFileName = Path.GetFileNameWithoutExtension(pFile);
    			
    
    			var fileHash = GetFileHash(pFile);
    		
    			if (BitConverter.ToString(targetHash) == BitConverter.ToString(fileHash))
    				listBox1.Items.Add(string.Format("{0} {1}",simpleFileName ,"✓"));
    			else
    				listBox1.Items.Add(string.Format("{0} {1}", simpleFileName, "x "));
    		}
    
    		private readonly HashAlgorithm _hashAlgorithm = HashAlgorithm.Create();
    		private byte[] GetFileHash(string fileName)
    		{
    			using (var stream = File.OpenRead(fileName))
    			{
    				return _hashAlgorithm.ComputeHash(stream);
    			};
    		}
    works great, thanks for your help, I now have a better understanding of how to pass data around my program.


    CuriousCoder

    Thursday, October 26, 2017 12:13 PM