Is there a built-in function to copy a directory in Dart?
Asked Answered
U

5

11

Is there a built-in function to copy a directory and recursively copy all the files (and other directories) in Dart?

Unmuzzle answered 29/11, 2014 at 17:5 Comment(0)
H
4

No, not to my knowledge there isn't. But Dart supports basic reading and writing of files from directories, so it stands to reason that this could be solved programmatically.

Check out this gist I found of a tool that would accomplish this process.

Basically, you would search the directory for files you wanted to copy and perform the copy operation:

newFile.writeAsBytesSync(element.readAsBytesSync());

to all file paths, new Path(element.path);, in the new Directory(newLocation);.

Edit:

But this is super inefficient, because the whole files has to be read in by the system and wrote back out to a file. You could just use a shell process spawned by Dart to take care of the process for you:

Process.run("cmd", ["/c", "copy", ...])
Hydrometallurgy answered 29/11, 2014 at 17:12 Comment(0)
S
6

Found https://pub.dev/documentation/io/latest/io/copyPath.html (or the sync version of same) which seems to be working for me. It's part of the io package https://pub.dev/documentation/io/latest/io/io-library.html available at https://pub.dev/packages/io.

It does the equivalent of cp -R <from> <to>.

Sufflate answered 9/9, 2019 at 0:6 Comment(0)
H
4

No, not to my knowledge there isn't. But Dart supports basic reading and writing of files from directories, so it stands to reason that this could be solved programmatically.

Check out this gist I found of a tool that would accomplish this process.

Basically, you would search the directory for files you wanted to copy and perform the copy operation:

newFile.writeAsBytesSync(element.readAsBytesSync());

to all file paths, new Path(element.path);, in the new Directory(newLocation);.

Edit:

But this is super inefficient, because the whole files has to be read in by the system and wrote back out to a file. You could just use a shell process spawned by Dart to take care of the process for you:

Process.run("cmd", ["/c", "copy", ...])
Hydrometallurgy answered 29/11, 2014 at 17:12 Comment(0)
U
2

Thank you James, wrote a quick function for it, but did it an alternative way. I'm unsure if this way would be anymore efficient or not?

/**
 * Retrieve all files within a directory
 */
Future<List<File>> allDirectoryFiles(String directory)
{
  List<File> frameworkFilePaths = [];

  // Grab all paths in directory
  return new Directory(directory).list(recursive: true, followLinks: false)
  .listen((FileSystemEntity entity)
  {
    // For each path, if the path leads to a file, then add to array list
    File file = new File(entity.path);
    file.exists().then((exists)
    {
      if (exists)
      {
        frameworkFilePaths.add(file);
      }
    });

  }).asFuture().then((_) { return frameworkFilePaths; });

}

Edit: OR! An even better approach (in some situations) would be to return a stream of files in the directory:

/**
 * Directory file stream
 *
 * Retrieve all files within a directory as a file stream.
 */
Stream<File> _directoryFileStream(Directory directory)
{
  StreamController<File> controller;
  StreamSubscription source;

  controller = new StreamController<File>(
    onListen: ()
    {
      // Grab all paths in directory
      source = directory.list(recursive: true, followLinks: false).listen((FileSystemEntity entity)
      {
        // For each path, if the path leads to a file, then add the file to the stream
        File file = new File(entity.path);
        file.exists().then((bool exists)
        {
          if (exists)
            controller.add(file);
        });
      },
      onError: () => controller.addError,
      onDone: () => controller.close
      );
    },
    onPause: () { if (source != null) source.pause(); },
    onResume: () { if (source != null) source.resume(); },
    onCancel: () { if (source != null) source.cancel(); }
  );

  return controller.stream;
}
Unmuzzle answered 29/11, 2014 at 19:20 Comment(0)
M
1
import 'package:path/path.dart' as path;

void copyDirectorySync(Directory source, Directory destination) {
  /// create destination folder if not exist
  if (!destination.existsSync()) {
    destination.createSync(recursive: true);
  }
  /// get all files from source (recursive: false is important here)
  source.listSync(recursive: false).forEach((entity) {
    final newPath = destination.path + Platform.pathSeparator + path.basename(entity.path);
    if (entity is File) {
      entity.copySync(newPath);
    } else if (entity is Directory) {
      copyDirectorySync(entity, Directory(newPath));
    }
  });
}

Maganmagana answered 3/5, 2023 at 16:38 Comment(1)
Thanks, the code works well, why no one upvotes :D. Use this one if you don't want to import final newPath = destination.path + Platform.pathSeparator + entity.path.split(Platform.pathSeparator).last;Nelrsa
E
0

I came across the same problem today. Turns out the io package from pub.dev solve this in a clean api: copyPath or copyPathSync

https://pub.dev/documentation/io/latest/io/copyPath.html

Eadmund answered 11/7, 2022 at 8:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.