copyWithProgress method

Future<File> copyWithProgress(
  1. String newPath,
  2. FileSystemEntityCopyProgressCb onProgress, {
  3. Context? pathContext,
  4. FileFactory fileFactory = File.new,
  5. FileSystemEntityTypeProvider typeProvider = FileSystemEntity.type,
})

Copies this file.

If newPath is a relative path, it is resolved against the current working directory (pathContext.current).

Returns a Future<File> that completes with a File for the copied file.

If newPath identifies an existing file, that file is removed first. If newPath identifies an existing directory, the operation fails and the future completes with an exception.

Implementation

Future<File> copyWithProgress(
  String newPath,
  FileSystemEntityCopyProgressCb onProgress, {
  lib_path.Context? pathContext,
  FileFactory fileFactory = File.new,
  FileSystemEntityTypeProvider typeProvider = FileSystemEntity.type,
}) async {
  pathContext ??= lib_path.context;

  // Resolve newPath against current directory, if it
  // is relative.
  final String resolvedNewPath;
  if (pathContext.isRelative(newPath)) {
    resolvedNewPath = pathContext.absolute(pathContext.current, newPath);
  } else {
    resolvedNewPath = newPath;
  }

  // Check that there exists no directory at newPath. Throw an exception
  // if anything other than a file already exists at newPath.
  final newPathType = await typeProvider(resolvedNewPath);

  if (FileSystemEntityType.file != newPathType &&
      FileSystemEntityType.notFound != newPathType) {
    throw PathExistsException(
      newPath,
      const OSError(),
      "Cannot copy the file at '$path' to '$resolvedNewPath', because "
      "the target already exists and is of type: $newPathType",
    );
  }

  final totalBytes = await length();
  var copiedBytes = 0;

  final newFile = fileFactory(resolvedNewPath);
  await newFile.recreate();

  final iStream = openRead();
  final sink = newFile.openWrite(mode: FileMode.writeOnly);

  await for (final bytes in iStream) {
    sink.add(bytes);
    copiedBytes += bytes.length;
    onProgress(totalBytes, copiedBytes);
  }

  await sink.flush();
  await sink.close();

  return newFile;
}