StuffItemTree.cs (7810B)
1 using System.Collections.Generic; 2 using System.IO; 3 using LanTool.Classes; 4 using System; 5 6 namespace LanTool 7 { 8 internal class StuffItemTree : StuffItem 9 { 10 #region private fields 11 12 private SortedDictionary<string, List<StuffItem>> stuffItemTreeByHash = new SortedDictionary<string, List<StuffItem>>(); 13 private SortedDictionary<string, List<StuffItem>> stuffItemTreeByName = new SortedDictionary<string, List<StuffItem>>(); 14 private long myDisksSpaceByClones = 0; 15 private long myDisksCountOfClones = 0; 16 private long myDisksCountOfAllowedClones = 0; 17 private long myDisksSpaceByAllowedClones = 0; 18 19 #endregion 20 21 /// <summary> 22 /// Root-Item der eigenen Platten 23 /// </summary> 24 public StuffItemTree(String path, Boolean isForeign) 25 { 26 Path = path; 27 IsOnForeignDisk = isForeign; 28 IsOnline = true; 29 } 30 31 #region public methods 32 33 public void CreateStuffItemTreeHash() 34 { 35 stuffItemTreeByHash.Clear(); 36 // Rücksetzen der Werte 37 myDisksCountOfClones = 0; 38 myDisksSpaceByClones = 0; 39 myDisksCountOfAllowedClones = 0; 40 myDisksSpaceByAllowedClones = 0; 41 // Füllen eigenen Disks 42 AddStuffItemToHashes( this ); 43 44 if ( !IsOnForeignDisk ) 45 { 46 Program.MainWindow.Log( "Dublettensuche auf eigenen Platten..." ); 47 // Ausgabe der Ergebnisse der Dublettenprüfung 48 if ( myDisksCountOfClones == 0 && myDisksCountOfAllowedClones == 0 ) 49 { 50 Program.MainWindow.LogHighlight( "Keine doppelten Dateien in 'Meine Platten', gut aufgeräumt!" ); 51 } 52 else 53 { 54 Program.MainWindow.LogError( "Doppelte Dateien in 'Meine Platten': " + myDisksCountOfClones.ToString() + ", das sind ca " + ( ( ( double )( myDisksSpaceByClones / 104857 ) ) / 10 ).ToString() + " MB wertvoller Plattenplatz!" ); 55 Program.MainWindow.LogWarning( "Erlaubte doppelte Dateien in 'Meine Platten': " + myDisksCountOfAllowedClones.ToString() + ", das sind ca " + ( ( ( double )( myDisksSpaceByAllowedClones / 104857 ) ) / 10 ).ToString() + " MB Plattenplatz!" ); 56 } 57 } 58 } 59 60 /// <summary> 61 /// Gibt die Dublettenliste des Items zurück (ohne das Item selbst). 62 /// Eine leere Liste bedeutet also, dass das Item keine Clones hat. 63 /// </summary> 64 public List<StuffItem> GetItemClones( StuffItem item ) 65 { 66 List<StuffItem> clonecopy = new List<StuffItem>(); 67 68 // Alle Items mit dem gleichen Hash merken 69 List<StuffItem> clones = GetItemsRecursive( item ); 70 71 // alle Items durchgehen und das Ursprungsitem wieder raussortieren 72 foreach ( StuffItem si in clones ) 73 { 74 if ( si != item ) 75 { 76 clonecopy.Add( si ); 77 } 78 } 79 return clonecopy; 80 } 81 82 /// <summary> 83 /// Zurückgeben, wie oft ein Item (Hash-Test) im MyDisks hängt 84 /// </summary> 85 /// <param name="item"></param> 86 /// <returns></returns> 87 public int GetRecursiveItemCount( StuffItem item ) 88 { 89 return GetItemsRecursive( item ).Count; 90 } 91 92 /// <summary> 93 /// Liefert alle StuffItems, die den gleichen Hash haben wie das übergebene 94 /// StuffItem 95 /// </summary> 96 /// <param name="item"></param> 97 /// <returns></returns> 98 public List<StuffItem> GetItemsRecursive( StuffItem item ) 99 { 100 List<StuffItem> retList = new List<StuffItem>(); 101 102 // keine Dubletten bei Dateien mit Lesefehler 103 if ( item.HasReadError ) 104 { 105 return retList; 106 } 107 108 // wenn die Datei in keiner Liste enthalten ist (weder Hash noch Name), dann raus 109 if ( !stuffItemTreeByHash.ContainsKey( item.Hash ) && !stuffItemTreeByName.ContainsKey( item.Name ) ) 110 { 111 return retList; 112 } 113 114 // Alle Items by Hash ermitteln 115 if (stuffItemTreeByHash.ContainsKey( item.Hash ) ) 116 { 117 retList.AddRange( stuffItemTreeByHash[ item.Hash ] ); 118 } 119 120 // restliche Prüfung nur, wenn die Namensprüfung angeschalten ist und die Datei auch enthalten ist 121 if ( Program.MainWindow.m_Config.IsTreatEqualNames && stuffItemTreeByName.ContainsKey( item.Name ) ) 122 { 123 // wenn die Datei überhaupt vorhanden ist, dann checken ob 124 foreach ( StuffItem si in stuffItemTreeByName[ item.Name ] ) 125 { 126 if ( !retList.Contains( si ) ) 127 { 128 retList.Add( si ); 129 } 130 } 131 } 132 133 return retList; 134 } 135 136 #endregion 137 138 #region Private methods 139 140 private void AddStuffItemToHashes( StuffItem si ) 141 { 142 // nur Dateien verarbeiten 143 if ( si.IsFile ) 144 { 145 // Name-Cache bearbeiten 146 if ( !stuffItemTreeByName.ContainsKey( si.Name ) ) 147 { 148 stuffItemTreeByName[ si.Name ] = new List<StuffItem>(); 149 stuffItemTreeByName[ si.Name ].Add( si ); 150 } 151 else 152 { 153 stuffItemTreeByName[ si.Name ].Add( si ); 154 } 155 156 // Hash-Cache bearbeiten 157 if ( !stuffItemTreeByHash.ContainsKey( si.Hash ) ) 158 { 159 stuffItemTreeByHash[ si.Hash ] = new List<StuffItem>(); 160 stuffItemTreeByHash[ si.Hash ].Add( si ); 161 } 162 else 163 { 164 stuffItemTreeByHash[ si.Hash ].Add( si ); 165 if ( si.IsIgnored ) 166 { 167 try 168 { 169 myDisksSpaceByAllowedClones += System.Convert.ToInt64( si.Hash.Substring( 33 ), 16 ); 170 } 171 catch 172 { 173 } 174 myDisksCountOfAllowedClones++; 175 } 176 else 177 { 178 try 179 { 180 myDisksSpaceByClones += System.Convert.ToInt64( si.Hash.Substring( 33 ), 16 ); 181 } 182 catch 183 { 184 } 185 myDisksCountOfClones++; 186 } 187 } 188 } 189 else 190 { 191 // Verzeichnis -> alle Childs durchgehen 192 foreach ( StuffItem csi in si.ChildItems ) 193 { 194 AddStuffItemToHashes( csi ); 195 } 196 } 197 } 198 199 internal void RemoveStuffItemFromHashes( StuffItem si ) 200 { 201 // StuffItem aus der Liste mit Hashes entfernen 202 stuffItemTreeByHash[ si.Hash ].Remove( si ); 203 204 // StuffItem aus der Namensliste entfernen 205 stuffItemTreeByName[ si.Name ].Remove( si ); 206 } 207 208 #endregion 209 210 #region FileSystemCache für Offline-Betrieb 211 212 private Dictionary<string, List<string>> offlineDirs = new Dictionary<string, List<string>>(); 213 private Dictionary<string, List<string>> offlineFiles = new Dictionary<string, List<string>>(); 214 215 public override Dictionary<string, List<string>> OfflineDirs 216 { 217 get 218 { 219 return offlineDirs; 220 } 221 } 222 223 public override Dictionary<string, List<string>> OfflineFiles 224 { 225 get 226 { 227 return offlineFiles; 228 } 229 } 230 231 /// <summary> 232 /// Offline Cache in eine Datei schreiben 233 /// </summary> 234 /// <param name="filename"></param> 235 public void SaveOfflineCacheToFile( string filename ) 236 { 237 using ( StreamWriter sw = File.CreateText( filename ) ) 238 { 239 foreach ( string sa in offlineDirs.Keys ) 240 { 241 foreach ( string sb in offlineDirs[ sa ] ) 242 { 243 sw.WriteLine( "D|" + sa + "|" + sb ); 244 } 245 } 246 foreach ( string sa in offlineFiles.Keys ) 247 { 248 foreach ( string sb in offlineFiles[ sa ] ) 249 { 250 sw.WriteLine( "F|" + sa + "|" + sb ); 251 } 252 } 253 } 254 255 Program.MainWindow.Log( "Offline-Verzeichnis wurde nach " + filename + " geschrieben" ); 256 } 257 258 259 /// <summary> 260 /// Offline-Cache aus einer Datei lesen 261 /// </summary> 262 /// <param name="filename"></param> 263 public void LoadOfflineCacheFromFile( string filename ) 264 { 265 using ( StreamReader sr = File.OpenText( filename ) ) 266 { 267 string line; 268 while ( ( line = sr.ReadLine() ) != null ) 269 { 270 string[] zeile = line.Split( '|' ); 271 if ( zeile[ 0 ] == "F" ) 272 { 273 if ( !OfflineFiles.ContainsKey( zeile[ 1 ] ) ) 274 { 275 OfflineFiles[ zeile[ 1 ] ] = new List<string>(); 276 } 277 OfflineFiles[ zeile[ 1 ] ].Add( zeile[ 2 ] ); 278 } 279 else 280 { 281 if ( !offlineDirs.ContainsKey( zeile[ 1 ] ) ) 282 { 283 offlineDirs[ zeile[ 1 ] ] = new List<string>(); 284 } 285 offlineDirs[ zeile[ 1 ] ].Add( zeile[ 2 ] ); 286 } 287 } 288 } 289 IsOnline = false; 290 } 291 292 /// <summary> 293 /// Simulation des Filesystems abschalten und zurücksetzen 294 /// </summary> 295 public void ResetOfflineCaches() 296 { 297 offlineDirs.Clear(); 298 offlineFiles.Clear(); 299 } 300 301 #endregion 302 } 303 }