Datei double finder.dart
Version vom 20. Januar 2021, 11:51 Uhr von Hamatoma (Diskussion | Beiträge) (Die Seite wurde neu angelegt: „= Links = * Projekt ddouble = Zielsetzung = Hier werden nur Besonderheiten der Datei double_finder.dart besprochen. Viele Teile dieser Datei sind ähnlic…“)
Links
Zielsetzung
Hier werden nur Besonderheiten der Datei double_finder.dart besprochen.
Viele Teile dieser Datei sind ähnlich wie [Datei search_engine.dart], z. B. das Festlegen der Optionen.
Die Klasse SearchEngine
Die Klasse implementiert ("realisiert") die Suche nach Duplikaten.
Die Attribute
Zuerst werden die Attribute definiert:
class DoubleFinder { static bool storeResult = false; final startTime = DateTime.now(); Map<int, List<FileInfo>> processedFiles = {}; final int verboseLevel; final startLength; final blockSize; int startBlockCount = 0; int fullBlockCounts = 0; int fullBlockFiles = 0; int doubles = 0; final lines = <String>[]; var hashBuilder = md5;
Der Konstruktor
DoubleFinder({this.verboseLevel, this.blockSize, this.startLength});
- Keine Besonderheiten.
Die Methode find()
Diese Methode erledigt den Kern des Programms.
/// Finds the duplicates in a list of [filePatterns]. void find(List<String> filePatterns, FileOptions fileOptions) { fileOptions.yieldDirectory = fileOptions.yieldLinkToDirectory = fileOptions.yieldLinkToFile = false; fileOptions.recursive = true; final supplier = FileSupplier( fileOptions: fileOptions, filePatterns: filePatterns, verboseLevel: verboseLevel); final toRemove = <FileInfo>[]; for (var filename in supplier.next()) { final file = supplier.currentEntity as File; final size = file.lengthSync(); if (size == 0){ continue; } var newEntry = FileInfo(filename, size); if (!processedFiles.containsKey(size)) { if (verboseLevel >= 4) { print('= new size $size'); } processedFiles[size] = [newEntry]; continue; } for (var processedFile in processedFiles[size]) { processedFile.hashStart ??= calcHash(file, calculateStartBlock: true); if (processedFile.hashStart == null) { toRemove.add(processedFile); continue; } newEntry.hashStart ??= calcHash(file, calculateStartBlock: true); if (newEntry.hashStart == null) { newEntry = null; break; } if (processedFile.hashStart == newEntry.hashStart) { if (verboseLevel >= 4) { print('= start block is the same: $filename ${processedFile.name}'); } processedFile.hashFull ??= calcHash(File(processedFile.name), calculateStartBlock: false); if (processedFile.hashFull == null) { toRemove.add(processedFile); continue; } newEntry.hashFull ??= calcHash(file, calculateStartBlock: false); if (newEntry.hashFull == null) { newEntry = null; break; } if (processedFile.hashFull == newEntry.hashFull) { doubles++; final line = '${newEntry.name} = ${processedFile.name} size: $size'; if (verboseLevel >= 2) { if (storeResult) { lines.add(line); } else { print(line); } } // we search only one duplicate. break; } } } for (var processedFile in toRemove) { processedFiles[size].remove(processedFile); } toRemove.clear(); if (newEntry != null) { processedFiles[size].add(newEntry); } } if (verboseLevel >= 1) { print('= duplicates: $doubles start blocks: $startBlockCount full blocks: $fullBlockFiles files with $fullBlockCounts blocks'); print(supplier.summary.join('\n')); final diff = DateTime.now().difference(startTime); final milliSeconds = (diff.inMilliseconds % 1000).toString().padLeft(3, '0'); print( '= runtime: ${diff.inHours}h${diff.inMinutes % 60}m${diff.inSeconds % 60}.$milliSeconds'); } if (!DoubleFinder.storeResult) { // Exit at once: release resources faster. exit(0); } }
fileOptions.yieldDirectory =
fileOptions.yieldLinkToDirectory = fileOptions.yieldLinkToFile = false;
Der Filenamensgenerator soll nur die Namen von reguläre Dateien liefern (keine Verzeichnisnamen, keine Links).final toRemove = <FileInfo>[];