copyRecursivelyWithProgress method
Copies all of the files in this directory to target
.
This is similar to cp -R <from> <to>
:
- Symlinks are supported.
- Existing files are over-written, if any.
- If
target
is withinthis
, throws ArgumentError. - If
this
andtarget
are canonically the same, no operation occurs.
Implementation
Future<void> copyRecursivelyWithProgress(
Directory target,
FileSystemEntityCopyProgressCb onProgress, {
bool followLinks = true,
LinkFactory linkFactory = Link.new,
FileFactory fileFactory = File.new,
DirectoryFactory dirFactory = Directory.new,
lib_path.Context? pathContext,
}) async {
pathContext ??= lib_path.context;
if (pathContext.canonicalize(path) ==
pathContext.canonicalize(target.path)) {
return;
}
if (pathContext.isWithin(path, target.path)) {
throw ArgumentError("Cannot copy $path to ${target.path}");
}
await target.create(recursive: true);
final totalBytes = await length();
var copiedBytes = 0;
await for (final file in list(recursive: true, followLinks: followLinks)) {
final copyTo = pathContext.join(
target.path,
pathContext.relative(file.path, from: path),
);
if (file is Directory) {
await dirFactory(copyTo).create(recursive: true);
} else if (file is File) {
var lastProgress = 0;
await fileFactory(file.path).copyWithProgress(
copyTo,
(_, progress) {
copiedBytes += progress - lastProgress;
lastProgress = progress;
onProgress(totalBytes, copiedBytes);
},
);
} else if (file is Link) {
final linkTarget = await file.target();
await linkFactory(copyTo).create(linkTarget, recursive: true);
}
}
}