fork download
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Security.Cryptography;
  5. using System.Drawing;
  6. using System.IO;
  7.  
  8. namespace Tools
  9. {
  10. class Program
  11. {
  12. static void Main(string[] args)
  13. {
  14. // Empfängt den Pfad des Ordners, in dem die exe-Datei liegt
  15. string WorkPath = Environment.CurrentDirectory;
  16.  
  17. // Hier suche ich einen in jedem Fall nicht vorhandenenen Ordner-Namen
  18. string ResultPath = WorkPath + "~";
  19. int i = 1;
  20. // Die Schleife läuft so lange weiter, bis der abgeänderte Pfad nicht existiert.
  21. // Damit die Änderung sich auch ändert, wird eine int-Variable hoch gezählt
  22. while (Directory.Exists(ResultPath + i.ToString())) i++;
  23. // Wenn die Schleife nun endet, speicher ich den neuen Pfad ab und erstelle den Ordner.
  24. ResultPath += i.ToString();
  25. Directory.CreateDirectory(ResultPath);
  26.  
  27. // Ruft alle Datei-Pfad im angegebenen Ordner ab
  28. string[] files = Directory.GetFiles(WorkPath);
  29.  
  30. // Hier kommen die ausgemisteten Dateien an, ohne Duplikate
  31. string[] Results = DistinctPictures(files);
  32. // Die Liste der resultierenden Datei-Pfade wird durchlaufen und jede Datei kopiert.
  33. // Der erste Parameter gibt die Quelle, der Zweite das Ziel an
  34. // im zweiten Parameter nehme ich dann den neuen, leeren Ordner-Pfad und hänge auf eine sichere Weise
  35. // Den Datei-Namen an. Dafür gibt es die Methode Path.Combine, die das fehlerfrei erledigt
  36. foreach (var item in Results)
  37. File.Copy(item, Path.Combine(ResultPath, Path.GetFileName(item)));
  38.  
  39. }
  40.  
  41. static string[] DistinctPictures(string[] files)
  42. {
  43. // Der Fehler-Text, der in die error.txt geschrieben wird
  44. string ErrorString = "";
  45. var PictureHashList = new byte[files.Length][];
  46. for (int i = 0; i < files.Length; i++)
  47. // Der try-Block wird in jedem Fall ausgeführt
  48. try
  49. {
  50. using (Image img = Image.FromFile(files[i]))
  51. PictureHashList[i] = new SHA256Managed().ComputeHash(
  52. (Byte[])new ImageConverter().ConvertTo(
  53. img, typeof(Byte[])));
  54. }
  55. // Der catch-Block wird immer dann ausgeführt, wenn im try-Block ein Laufzeitfehler auf tritt
  56. catch (Exception ex)
  57. {
  58. // Exception ist die Basis-Klasse für alle Fehler-Klassen.
  59. // Dort kann man verschiedene Typen verwenden und so z.B.
  60. // für die Ableitung "FileNotFoundException" eine gesonderte Fehlerbehandlung einbauen,
  61. // Wenn eine Datei nicht gefunden wurde
  62. // Ich hab hier einfach nur Exception genommen, um den Absturz des Programmes in jedem Fall zu verhindern.
  63. ErrorString += "Error:";
  64. ErrorString += " \r\nDatei: " + files[i];
  65. ErrorString += " \r\nFehler: " + ex.Message;
  66. ErrorString += "\r\n" + new string('-', 20);
  67. }
  68. // Hier schreibe ich die error.txt
  69. // Ein FileStream ist Stream, der geschlossen werden muss, daher verwende ich hier using
  70. // Der Parameter "FileMode.Create" gibt an, dass die Datei entweder erstellt oder überschrieben wird
  71. if (ErrorString != "")
  72. using (FileStream file = new FileStream("error.txt", FileMode.Create))
  73. // Da der FileStream nur Bytes schreiben kann, brauche ich einen StreamWriter,
  74. // der für mich in den FileStream schreibt. Auch der muss danach wieder geschlossen werden,
  75. // daher auch hier wieder using
  76. using (StreamWriter writer = new StreamWriter(file))
  77. writer.Write(ErrorString);
  78.  
  79.  
  80.  
  81. var dictionary = new Dictionary<byte[], string>();
  82. for (int i = 0; i < PictureHashList.Length; i++)
  83. if (PictureHashList[i] != null)
  84. if (!new Func<bool>(() =>
  85. {
  86. foreach (var item in dictionary.Keys.ToList())
  87. if (PictureHashList[i].SequenceEqual(item))
  88. return true;
  89. return false;
  90. }).Invoke())
  91. dictionary.Add(PictureHashList[i], files[i]);
  92. return dictionary.Values.ToArray();
  93. }
  94. }
  95. }
Runtime error #stdin #stdout 0.04s 36456KB
stdin
Standard input is empty
stdout
Standard output is empty