fdups method

Stream<Es> fdups()

find duplicate files

Implementation

Stream<Es> fdups() {
  final action = PathAction.fdups.name, chk = 'validator';
  argErr ??= validator();
  if (argErr!.isNotEmpty) throw ArgumentError.value(argErr, action, chk);

  final fields = fieldsFromOptions(fmtFields);
  final fseType = FileSystemEntityType.file;

  final crcMap = <int, List<Es>>{};
  // if (!fileds.contains(FormatField.extra)) fileds.add(FormatField.extra);

  final stream = scEntity.stream;
  final fStream =
      stream.where((event) => event.fs.type == fseType).asBroadcastStream();
  late StreamSubscription subs;
  subs = fStream.listen(
    (event) {
      var (entity, stat, extra) = event.asRecord;
      try {
        final crc64 = getCrc64(File(entity.path).readAsBytesSync());
        extra = 'hash:$crc64';
        crcMap.putIfAbsent(crc64, () => []);
        crcMap[crc64]?.add(event.copyWith(extra: extra));
      } catch (e, s) {
        logger.stderr('e, $action, data, delete ${entity.path}');
        scEntity.addError(e, s);
      }
    },
    cancelOnError: cancelOnError,
    onDone: () {
      logger.trace('d, $action, done.');
      for (var item in crcMap.entries) {
        final key = item.key;
        final dups = item.value;
        if (dups.length > 1) {
          logger.stdout('i, $action, hash:$key');
          final ok = true;
          for (var dup in dups) {
            // final (entity, stat, extra) = dup;
            final line = Formatter(dup.fse, dup.fs, dup.extra, action,
                shows: fields, ok: ok);
            logger.stdout(line.toString());
          }
        }
      }
    },
    onError: (e, s) {
      if (cancelOnError) {
        exitCode = ExitCodeExt.error.code;
        subs.cancel();
      }

      logger
        ..trace('d, $action, cancelOnError:$cancelOnError')
        ..stderr('e, $action, error. $e')
        ..stderr(kIsDebug ? '$s' : '');
    }, // onError
  );

  return fStream;
}