Hello, everybody. The code below, works very slowly, about 10 seconds per iteration. How to improve him?
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
namespace Compare
{
public class Comparer
{
public static List<string> CompareLength(string file, List<string> arr)
{
List<string> result = new List<string>();
foreach (string item in arr)
if (new FileInfo(item).Length == new FileInfo(file).Length)
result.Add(item);
return result;
}
public static void CompareFilesRec(List<string> array)
{
List<string> outp = new List<string>();
int i = 0;
while (i < array.Count)
{
List<string> fromAll = Comparer.CompareLength(array[i], array);
string chosen = array[i];
if (fromAll.Count != 0)
foreach (var f2 in fromAll)
{
if (Checksum.CompareHash(chosen, f2))
{
outp.Add(f2);
array.Remove(f2);
}
else { i++; }
}
Comparer.ShowResults(outp);
outp.Clear();
}
}
public static void ShowResults(List<string> results)
{
if (results.Count >= 2)
{
foreach (var element in results)
{
Console.WriteLine(element);
}
Console.WriteLine();
}
}
}
}
Checksum.CompareHash
static public bool CompareHash(string file1, string file2)
{
long FirstSize = new FileInfo(file1).Length;
long SecondSize = new FileInfo(file2).Length;
byte[] buffer1 = new byte[FirstSize];
byte[] buffer2 = new byte[SecondSize];
try
{
using (var mmf1 = MemoryMappedFile.CreateFromFile(file1, FileMode.OpenOrCreate, null, 0))
using (var mmf2 = MemoryMappedFile.CreateFromFile(file2, FileMode.OpenOrCreate, null, 0))
using (var reader1 = mmf1.CreateViewStream())
using (var reader2 = mmf2.CreateViewStream())
{
try
{
reader1.Read(buffer1, 0, (int)FirstSize);
reader2.Read(buffer2, 0, (int)SecondSize);
}
catch (Exception ex)
{
Console.WriteLine("Error: {0}", ex.Message);
}
if (buffer1.Length != buffer2.Length || Crc8.ComputeChecksum(buffer1) != Crc8.ComputeChecksum(buffer2))
return false;
}
}
catch (IOException) { }
catch (UnauthorizedAccessException) { }
return true;
}
So, I realized that solution, check it:
namespace Compare
{
public class Comparer
{
public static List<string> CompareLength(string file, List<string> arr)
{
List<string> result = new List<string>();
foreach (string item in arr)
if (new FileInfo(item).Length == new FileInfo(file).Length && Checksum.CompareHash(file,item))
result.Add(item);
return result;
}
public static void CompareFilesRec(List<string> array)
{
Dictionary<long, List<string>> di = new Dictionary<long,List<string>>();
int i = 0;
while (i < array.Count)
{
long size = new FileInfo(array[i]).Length;
List<string> fromAll = Comparer.CompareLength(array[i], array);
if (di.ContainsKey(size))
{
fromAll.Clear();
array.Remove(array[i]);
}
else
{
di.Add(size, fromAll);
i++;
}
}
ShowResults(di);
}
public static void ShowResults(Dictionary<long, List<string>> dic)
{
foreach(var element in dic)
{
foreach (var outer in element.Value)
{
Console.WriteLine(outer);
}
Console.WriteLine();
}
}
}
}
Also i changed the hashing function:
namespace Compare
{
public class Checksum
{
static public bool CompareHash(string file1, string file2)
{
long FirstSize = new FileInfo(file1).Length;
long SecondSize = new FileInfo(file2).Length;
SHA256 sha1 = SHA256Managed.Create();
SHA256 sha2 = SHA256Managed.Create();
byte[] buffer1 = new byte[FirstSize];
byte[] buffer2 = new byte[SecondSize];
try
{
using (var mmf1 = MemoryMappedFile.CreateFromFile(file1, FileMode.OpenOrCreate, null, 0))
using (var mmf2 = MemoryMappedFile.CreateFromFile(file2, FileMode.OpenOrCreate, null, 0))
using (var reader1 = mmf1.CreateViewStream())
using (var reader2 = mmf2.CreateViewStream())
{
try
{
reader1.Read(buffer1, 0, (int)FirstSize);
reader2.Read(buffer2, 0, (int)SecondSize);
}
catch (Exception ex)
{
Console.WriteLine("Error: {0}", ex.Message);
}
if (buffer1.Length != buffer2.Length && sha1.ComputeHash(buffer1) != sha2.ComputeHash(buffer2))
return false;
}
}
catch (IOException) { }
catch (UnauthorizedAccessException) { }
return true;
}
}
}
Please, tell me my errors in code above...