| // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| part of dart.io; |
| |
| /// A reference to a directory (or _folder_) on the file system. |
| /// |
| /// A [Directory] is an object holding a [path] on which operations can |
| /// be performed. The path to the directory can be [absolute] or relative. |
| /// It allows access to the [parent] directory, |
| /// since it is a [FileSystemEntity]. |
| /// |
| /// The [Directory] also provides static access to the system's temporary |
| /// file directory, [systemTemp], and the ability to access and change |
| /// the [current] directory. |
| /// |
| /// Create a new [Directory] to give access the directory with the specified |
| /// path: |
| /// ```dart |
| /// var myDir = Directory('myDir'); |
| /// ``` |
| /// Most instance methods of [Directory] exist in both synchronous |
| /// and asynchronous variants, for example, [create] and [createSync]. |
| /// Unless you have a specific reason for using the synchronous version |
| /// of a method, prefer the asynchronous version to avoid blocking your program. |
| /// |
| /// ## Create a directory |
| /// |
| /// The following code sample creates a directory using the [create] method. |
| /// By setting the `recursive` parameter to true, you can create the |
| /// named directory and all its necessary parent directories, |
| /// if they do not already exist. |
| /// ```dart |
| /// import 'dart:io'; |
| /// |
| /// void main() async { |
| /// // Creates dir/ and dir/subdir/. |
| /// var directory = await Directory('dir/subdir').create(recursive: true); |
| /// print(directory.path); |
| /// } |
| /// ``` |
| /// ## List the entries of a directory |
| /// |
| /// Use the [list] or [listSync] methods to get the files and directories |
| /// contained in a directory. |
| /// Set `recursive` to true to recursively list all subdirectories. |
| /// Set `followLinks` to true to follow symbolic links. |
| /// The list method returns a [Stream] of [FileSystemEntity] objects. |
| /// Listen on the stream to access each object as it is found: |
| /// ```dart |
| /// import 'dart:io'; |
| /// |
| /// void main() async { |
| /// // Get the system temp directory. |
| /// var systemTempDir = Directory.systemTemp; |
| /// |
| /// // List directory contents, recursing into sub-directories, |
| /// // but not following symbolic links. |
| /// await for (var entity in |
| /// systemTempDir.list(recursive: true, followLinks: false)) { |
| /// print(entity.path); |
| /// } |
| /// } |
| /// ``` |
| /// ## The use of asynchronous methods |
| /// |
| /// I/O operations can block a program for some period of time while it waits for |
| /// the operation to complete. To avoid this, all |
| /// methods involving I/O have an asynchronous variant which returns a [Future]. |
| /// This future completes when the I/O operation finishes. While the I/O |
| /// operation is in progress, the Dart program is not blocked, |
| /// and can perform other operations. |
| /// |
| /// For example, |
| /// the [exists] method, which determines whether the directory exists, |
| /// returns a boolean value asynchronously using a [Future]. |
| /// ```dart |
| /// import 'dart:io'; |
| /// |
| /// void main() async { |
| /// final myDir = Directory('dir'); |
| /// var isThere = await myDir.exists(); |
| /// print(isThere ? 'exists' : 'non-existent'); |
| /// } |
| /// ``` |
| /// |
| /// In addition to [exists], the [stat], [rename], |
| /// and other methods are also asynchronous. |
| /// |
| /// ## Other resources |
| /// |
| /// * The [Files and directories](https://dart.dev/guides/libraries/library-tour#files-and-directories) |
| /// section of the library tour. |
| /// |
| /// * [Write Command-Line Apps](https://dart.dev/tutorials/server/cmdline), |
| /// a tutorial about writing command-line apps, includes information about |
| /// files and directories. |
| @pragma("vm:entry-point") |
| abstract class Directory implements FileSystemEntity { |
| /// Gets the path of this directory. |
| String get path; |
| |
| /// Creates a [Directory] object. |
| /// |
| /// If [path] is a relative path, it will be interpreted relative to the |
| /// current working directory (see [Directory.current]), when used. |
| /// |
| /// If [path] is an absolute path, it will be immune to changes to the |
| /// current working directory. |
| @pragma("vm:entry-point") |
| factory Directory(String path) { |
| final IOOverrides? overrides = IOOverrides.current; |
| if (overrides == null) { |
| return new _Directory(path); |
| } |
| return overrides.createDirectory(path); |
| } |
| |
| @pragma("vm:entry-point") |
| factory Directory.fromRawPath(Uint8List path) { |
| // TODO(bkonyi): Handle overrides. |
| return new _Directory.fromRawPath(path); |
| } |
| |
| /// Create a [Directory] from a URI. |
| /// |
| /// If [uri] cannot reference a directory this throws [UnsupportedError]. |
| factory Directory.fromUri(Uri uri) => new Directory(uri.toFilePath()); |
| |
| /// Creates a directory object pointing to the current working |
| /// directory. |
| static Directory get current { |
| final IOOverrides? overrides = IOOverrides.current; |
| if (overrides == null) { |
| return _Directory.current; |
| } |
| return overrides.getCurrentDirectory(); |
| } |
| |
| /// A [Uri] representing the directory's location. |
| /// |
| /// The URI's scheme is always "file" if the entity's [path] is |
| /// absolute, otherwise the scheme will be empty and the URI relative. |
| /// The URI's path always ends in a slash ('/'). |
| Uri get uri; |
| |
| /// Sets the current working directory of the Dart process. |
| /// |
| /// This affects all running isolates. |
| /// The new value set can be either a [Directory] or a [String]. |
| /// |
| /// The new value is passed to the OS's system call unchanged, so a |
| /// relative path passed as the new working directory will be |
| /// resolved by the OS. |
| /// |
| /// Note that setting the current working directory is a synchronous |
| /// operation and that it changes the working directory of *all* |
| /// isolates. |
| /// |
| /// Use this with care — especially when working with asynchronous |
| /// operations and multiple isolates. Changing the working directory, |
| /// while asynchronous operations are pending or when other isolates |
| /// are working with the file system, can lead to unexpected results. |
| static void set current(path) { |
| final IOOverrides? overrides = IOOverrides.current; |
| if (overrides == null) { |
| _Directory.current = path; |
| return; |
| } |
| overrides.setCurrentDirectory(path); |
| } |
| |
| /// Creates the directory if it doesn't exist. |
| /// |
| /// If [recursive] is false, only the last directory in the path is |
| /// created. If [recursive] is true, all non-existing path components |
| /// are created. If the directory already exists nothing is done. |
| /// |
| /// Returns a `Future<Directory>` that completes with this |
| /// directory once it has been created. If the directory cannot be |
| /// created the future completes with an exception. |
| Future<Directory> create({bool recursive = false}); |
| |
| /// Synchronously creates the directory if it doesn't exist. |
| /// |
| /// If [recursive] is false, only the last directory in the path is |
| /// created. If [recursive] is true, all non-existing path components |
| /// are created. If the directory already exists nothing is done. |
| /// |
| /// If the directory cannot be created an exception is thrown. |
| void createSync({bool recursive = false}); |
| |
| /// The system temp directory. |
| /// |
| /// This is the directory provided by the operating system for creating |
| /// temporary files and directories in. |
| /// The location of the system temporary directory is platform-dependent, |
| /// and may be controlled by an environment variable on some platforms. |
| static Directory get systemTemp { |
| final IOOverrides? overrides = IOOverrides.current; |
| if (overrides == null) { |
| return _Directory.systemTemp; |
| } |
| return overrides.getSystemTempDirectory(); |
| } |
| |
| /// Creates a temporary directory in this directory. |
| /// |
| /// Additional random characters are appended to [prefix] |
| /// to produce a unique directory name. |
| /// If [prefix] is missing or null, the empty string is used as [prefix]. |
| /// |
| /// Returns a `Future<Directory>` that completes with the newly |
| /// created temporary directory. |
| Future<Directory> createTemp([String? prefix]); |
| |
| /// Synchronously creates a temporary directory in this directory. |
| /// |
| /// Additional random characters are appended to [prefix] to produce |
| /// a unique directory name. If [prefix] is missing or null, the empty |
| /// string is used as [prefix]. |
| /// |
| /// Returns the newly created temporary directory. |
| Directory createTempSync([String? prefix]); |
| |
| Future<String> resolveSymbolicLinks(); |
| |
| String resolveSymbolicLinksSync(); |
| |
| /// Renames this directory. |
| /// |
| /// Returns a `Future<Directory>` that completes |
| /// with a [Directory] for the renamed directory. |
| /// |
| /// If [newPath] identifies an existing directory, that directory is |
| /// removed first. |
| /// If [newPath] identifies an existing file, the operation |
| /// fails and the future completes with an exception. |
| Future<Directory> rename(String newPath); |
| |
| /// Synchronously renames this directory. |
| /// |
| /// Returns a [Directory] for the renamed directory. |
| /// |
| /// If [newPath] identifies an existing directory, that directory is |
| /// removed first. |
| /// If [newPath] identifies an existing file the operation |
| /// fails and an exception is thrown. |
| Directory renameSync(String newPath); |
| |
| /// A [Directory] whose path is the absolute path of [this]. |
| /// |
| /// The absolute path is computed by prefixing |
| /// a relative path with the current working directory, |
| /// or by returning an absolute path unchanged. |
| Directory get absolute; |
| |
| /// Lists the sub-directories and files of this [Directory]. |
| /// |
| /// Optionally recurses into sub-directories. |
| /// |
| /// If [followLinks] is `false`, then any symbolic links found |
| /// are reported as [Link] objects, rather than as directories or files, |
| /// and are not recursed into. |
| /// |
| /// If [followLinks] is `true`, then working links are reported as |
| /// directories or files, depending on what they point to, |
| /// and links to directories are recursed into f [recursive] is `true`. |
| /// |
| /// Broken links are reported as [Link] objects. |
| /// |
| /// If a symbolic link makes a loop in the file system, then a recursive |
| /// listing will not follow a link twice in the |
| /// same recursive descent, but will report it as a [Link] |
| /// the second time it is seen. |
| /// |
| /// The result is a stream of [FileSystemEntity] objects |
| /// for the directories, files, and links. |
| Stream<FileSystemEntity> list( |
| {bool recursive = false, bool followLinks = true}); |
| |
| /// Lists the sub-directories and files of this [Directory]. |
| /// Optionally recurses into sub-directories. |
| /// |
| /// If [followLinks] is `false`, then any symbolic links found |
| /// are reported as [Link] objects, rather than as directories or files, |
| /// and are not recursed into. |
| /// |
| /// If [followLinks] is `true`, then working links are reported as |
| /// directories or files, depending on what they point to, |
| /// and links to directories are recursed into if `recursive` is `true`. |
| /// |
| /// Broken links are reported as [Link] objects. |
| /// |
| /// If a link makes a loop in the file system, then a recursive |
| /// listing will not follow a link twice in the |
| /// same recursive descent, but will report it as a [Link] |
| /// the second time it is seen. |
| /// |
| /// Returns a [List] containing [FileSystemEntity] objects for the |
| /// directories, files, and links. |
| List<FileSystemEntity> listSync( |
| {bool recursive = false, bool followLinks = true}); |
| |
| /// Returns a human readable representation of this [Directory]. |
| String toString(); |
| } |