lantool

ein feines Tool für LANs (damals)
git clone https://git.clttr.info/lantool.git
Log (Feed) | Files | Refs (Tags) | README | LICENSE

GlobalCache.cs (7574B)


      1 using System;
      2 using System.Collections.Generic;
      3 using System.IO;
      4 using System.Security.Cryptography;
      5 
      6 namespace LanTool.Classes
      7 {
      8 	/// <summary>
      9 	/// Beinhaltet die globalen CacheListe des LanTools
     10 	/// </summary>
     11 	public class GlobalCache : IDisposable
     12 	{
     13 		#region Konstanten für die Caches
     14 
     15 		private const string cHashKeyCacheFile = "LanTool.cache";
     16 		private const string cHashKeyExcludeFile = "LanTool.exclude";
     17 		private const string cHashKeyIgnoreFile = "LanTool.ignore";
     18 
     19 		#endregion
     20 
     21 		#region Properties
     22 
     23 		/// <summary>
     24 		/// Cache mit allen Hash-Werten von bekannten Dateien
     25 		/// </summary>
     26 		public SortedDictionary<string, string> HashCache { get; private set; }
     27 		/// <summary>
     28 		/// Cache mit allen Hash-Werten, die gesperrt sind
     29 		/// </summary>
     30 		public List<String> ExcludeCache { get; private set; }
     31 		/// <summary>
     32 		/// Cache mit allen Hash-Werten, bei denen Dubletten ignoriert werden
     33 		/// </summary>
     34 		public List<String> IgnoreCache { get; private set; }
     35 
     36 		#endregion
     37 
     38 		#region Fields mit den Caches
     39 
     40 		private long hashOldInCache = 0;
     41 		private long hashNewInCache = 0;
     42 		private string _basePath;
     43 
     44 		private MD5 md5;
     45 
     46 		#endregion
     47 
     48 		/// <summary>
     49 		/// Konstruktor für den globalen Cache
     50 		/// Legt die Cachelisten an und füllt diese von den Platten
     51 		/// </summary>
     52 		/// <param name="basePath">Standard-Pfad</param>
     53 		public GlobalCache(string basePath)
     54 		{
     55 			this._basePath = basePath;
     56 
     57 			this.HashCache = new SortedDictionary<string, string>();
     58 			this.ExcludeCache = new List<string>();
     59 			this.IgnoreCache = new List<string>();
     60 
     61 			md5 = MD5.Create();
     62 
     63 			// Caches einlesen
     64 			LoadCacheFromDisk();
     65 			LoadExcludeListFromDisk();
     66 			LoadIgnoreListFromDisk();
     67 		}
     68 
     69 		/// <summary>
     70 		/// Speichert alle Liste auf Festplatte
     71 		/// </summary>
     72 		public void Dispose()
     73 		{
     74 			Dispose(true);
     75 			GC.SuppressFinalize(this);
     76 		}
     77 
     78 		/// <summary>
     79 		/// Speichert alle Liste auf Festplatte
     80 		/// </summary>
     81 		/// <param name="yes"></param>
     82 		protected virtual void Dispose(Boolean yes)
     83 		{
     84 			if (yes)
     85 			{
     86 			}
     87 
     88 			SaveCacheToDisk();
     89 			SaveExcludeListToDisk();
     90 			SaveIgnoreListToDisk();
     91 		}
     92 
     93 		#region Behandlung der globalen Cache-Liste
     94 
     95 		/// <summary>
     96 		/// MD5-Cache von der Platte laden
     97 		/// </summary>
     98 		private void LoadCacheFromDisk()
     99 		{
    100 			HashCache.Clear();
    101 			if (File.Exists(_basePath + cHashKeyCacheFile))
    102 			{
    103 				using (StreamReader cacheReader = File.OpenText(_basePath + cHashKeyCacheFile))
    104 				{
    105 					string s;
    106 					while ((s = cacheReader.ReadLine()) != null)
    107 					{
    108 						if ( s.Length > 44 )
    109 						{
    110 							HashCache[ s.Substring( 44 ) ] = s.Substring( 0, 43 );
    111 						}
    112 					}
    113 				}
    114 				Program.MainWindow.Log(cHashKeyCacheFile + " wurde mit " + HashCache.Keys.Count.ToString() + " Einträgen geladen.");
    115 			}
    116 			else
    117 			{
    118 				Program.MainWindow.LogWarning(cHashKeyCacheFile + " nicht vorhanden.");
    119 			}
    120 		}
    121 
    122 		/// <summary>
    123 		/// MD5-Cache auf Platte speichern
    124 		/// </summary>
    125 		public void SaveCacheToDisk()
    126 		{
    127 			try
    128 			{
    129 				using (StreamWriter sw = File.CreateText(_basePath + cHashKeyCacheFile))
    130 				{
    131 					foreach (KeyValuePair<string, string> di in HashCache)
    132 					{
    133 						sw.WriteLine(di.Value + "/" + di.Key);
    134 					}
    135 				}
    136 				Program.MainWindow.Log(cHashKeyCacheFile + " wurde mit " + HashCache.Keys.Count.ToString() + " Einträgen gespeichert (" + hashNewInCache.ToString() + " neue Einträge, " + hashOldInCache.ToString() + " Treffer)");
    137 			}
    138 			catch (Exception e)
    139 			{
    140 				Program.MainWindow.LogError(cHashKeyCacheFile + " konnte nicht gespeichert werden: " + e.Message);
    141 			}
    142 		}
    143 
    144 		/// <summary>
    145 		/// Löschen des Hash-Caches
    146 		/// </summary>
    147 		public void Clear()
    148 		{
    149 			HashCache.Clear();
    150 
    151 			hashNewInCache = 0;
    152 			hashOldInCache = 0;
    153 			
    154 			SaveCacheToDisk();
    155 		}
    156 
    157 		/// <summary>
    158 		/// Aus Datei einen Hashkey erzeugen oder aus dem Cache entnehmen
    159 		/// </summary>
    160 		/// <param name="file">Datei</param>
    161 		/// <returns>Hash-Key</returns>
    162 		public string GetHashCodeFromFileHeader(string file)
    163 		{
    164 			if (String.IsNullOrEmpty(file))
    165 			{
    166 				return String.Empty;
    167 			}
    168 
    169 			Int32 md5HashSize = Program.MainWindow.m_Config.MD5FileSize;
    170 
    171 			// Nachsehen, ob der Länge / Dateipfad gecached sind
    172 			if (HashCache.ContainsKey(md5HashSize + " " + file))
    173 			{
    174 				hashOldInCache++;
    175 				return HashCache[md5HashSize + " " + file];
    176 			}
    177 
    178 			// wenn die Datei nicht existiert, keinen Fehler melden
    179 			// sondern leeren String, Datei wird später als Lesefehler markiert
    180 			if (!File.Exists(file))
    181 			{
    182 				return String.Empty;
    183 			}
    184 
    185 			try
    186 			{
    187 				// Teil 1 des Hashcodes ist die Dateigröße
    188 				FileInfo fi = new FileInfo(file);
    189 				string hash = fi.Length.ToString("X10");
    190 				// Teil 2 des Hascode ist das md5 über x Bytes. Bei Netzwerkzugriff
    191 				// ist das etwas zu viel die ganzen Dateien zu lesen
    192 				byte[] buffer = new byte[md5HashSize];
    193 				using (FileStream fs = fi.OpenRead())
    194 				{
    195 					int gelesen = fs.Read(buffer, 0, md5HashSize);
    196 
    197 					// Wenn die Datei leer ist, den Dateinamen nehmen
    198 					if (gelesen == 0)
    199 					{
    200 						for (int i = 0; i < file.Length; i++)
    201 							buffer[i] = (byte)file[i];
    202 					}
    203 				}
    204 
    205 				byte[] mdhash = md5.ComputeHash(buffer);
    206 				hash = "/" + hash;
    207 				foreach (byte b in mdhash)
    208 				{
    209 					hash = b.ToString("X2") + hash;
    210 				}
    211 
    212 				// Im Cache ablegen für weitere Verwendung
    213 				HashCache[md5HashSize + " " + file] = hash;
    214 				hashNewInCache++;
    215 				return hash;
    216 			}
    217 			catch
    218 			{
    219 				return String.Empty;
    220 			}
    221 		}
    222 
    223 		#endregion
    224 
    225 		/// <summary>
    226 		/// Exclude-Liste von Platte laden
    227 		/// </summary>
    228 		private void LoadExcludeListFromDisk()
    229 		{
    230 			ExcludeCache.Clear();
    231 			if (File.Exists(_basePath + cHashKeyExcludeFile))
    232 			{
    233 				// Alle Zeilen der Datei in den Cache einlesen
    234 				ExcludeCache.AddRange(File.ReadAllLines(_basePath + cHashKeyExcludeFile));
    235 
    236 				Program.MainWindow.Log(cHashKeyExcludeFile + " wurde mit " + ExcludeCache.Count.ToString() + " Einträgen geladen");
    237 			}
    238 			else
    239 			{
    240 				Program.MainWindow.LogWarning(cHashKeyExcludeFile + " nicht vorhanden.");
    241 			}
    242 		}
    243 
    244 		/// <summary>
    245 		/// Exclude-Liste auf Platte speichern
    246 		/// </summary>
    247 		public void SaveExcludeListToDisk()
    248 		{
    249 			try
    250 			{
    251 				// Alle Zeilen des Exclude-Caches in die Datei schreiben
    252 				File.WriteAllLines(_basePath + cHashKeyExcludeFile, ExcludeCache.ToArray());
    253 
    254 				Program.MainWindow.Log(cHashKeyExcludeFile + " wurde mit " + ExcludeCache.Count.ToString() + " Einträgen gespeichert");
    255 			}
    256 			catch (Exception e)
    257 			{
    258 				Program.MainWindow.LogError(cHashKeyExcludeFile + "konnte nicht gespeichert werden: " + e.Message);
    259 			}
    260 		}
    261 
    262 		/// <summary>
    263 		/// Exclude-Liste von Platte laden
    264 		/// </summary>
    265 		private void LoadIgnoreListFromDisk()
    266 		{
    267 			IgnoreCache.Clear();
    268 			if (File.Exists(_basePath + cHashKeyIgnoreFile))
    269 			{
    270 				// Alle Zeilen in den IgnoreCache laden
    271 				IgnoreCache.AddRange(File.ReadAllLines(_basePath + cHashKeyIgnoreFile));
    272 
    273 				Program.MainWindow.Log(cHashKeyIgnoreFile + " wurde mit " + IgnoreCache.Count.ToString() + " Einträgen geladen");
    274 			}
    275 			else
    276 			{
    277 				Program.MainWindow.LogWarning(cHashKeyIgnoreFile + " nicht vorhanden.");
    278 			}
    279 		}
    280 
    281 		/// <summary>
    282 		/// Exclude-Liste auf Platte speichern
    283 		/// </summary>
    284 		public void SaveIgnoreListToDisk()
    285 		{
    286 			try
    287 			{
    288 				File.WriteAllLines(_basePath + cHashKeyIgnoreFile, IgnoreCache.ToArray());
    289 				Program.MainWindow.Log(cHashKeyIgnoreFile + " wurde mit " + IgnoreCache.Count.ToString() + " Einträgen gespeichert");
    290 			}
    291 			catch (Exception e)
    292 			{
    293 				Program.MainWindow.LogError(cHashKeyIgnoreFile + "konnte nicht gespeichert werden: " + e.Message);
    294 			}
    295 		}
    296 	}
    297 }