Appearance
Directory abstract interface
abstract interface class Directory implements FileSystemEntityA 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' : 'nonexistent');
}In addition to exists, the stat, rename, and other methods are also asynchronous.
Other resources
The Files and directories section of the library tour.
Write Command-Line Apps, a tutorial about writing command-line apps, includes information about files and directories.
Implemented types
Constructors
Directory() factory
factory Directory(String 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.
Implementation
dart
@pragma("vm:entry-point")
factory Directory(String path) {
final IOOverrides? overrides = IOOverrides.current;
if (overrides == null) {
return _Directory(path);
}
return overrides.createDirectory(path);
}Directory.fromRawPath() factory
factory Directory.fromRawPath(Uint8List path)Implementation
dart
@pragma("vm:entry-point")
factory Directory.fromRawPath(Uint8List path) {
// TODO(bkonyi): Handle overrides.
return _Directory.fromRawPath(path);
}Directory.fromUri() factory
factory Directory.fromUri(Uri uri)Create a Directory from a URI.
If uri cannot reference a directory this throws UnsupportedError.
Implementation
dart
factory Directory.fromUri(Uri uri) => Directory(uri.toFilePath());Properties
absolute no setter override
Directory get absoluteA Directory whose path is the absolute path of this Directory.
The absolute path is computed by prefixing a relative path with the current working directory, or by returning an absolute path unchanged.
Implementation
dart
Directory get absolute;hashCode no setter inherited
int get hashCodeThe hash code for this object.
A hash code is a single integer which represents the state of the object that affects operator == comparisons.
All objects have hash codes. The default hash code implemented by Object represents only the identity of the object, the same way as the default operator == implementation only considers objects equal if they are identical (see identityHashCode).
If operator == is overridden to use the object state instead, the hash code must also be changed to represent that state, otherwise the object cannot be used in hash based data structures like the default Set and Map implementations.
Hash codes must be the same for objects that are equal to each other according to operator ==. The hash code of an object should only change if the object changes in a way that affects equality. There are no further requirements for the hash codes. They need not be consistent between executions of the same program and there are no distribution guarantees.
Objects that are not equal are allowed to have the same hash code. It is even technically allowed that all instances have the same hash code, but if clashes happen too often, it may reduce the efficiency of hash-based data structures like HashSet or HashMap.
If a subclass overrides hashCode, it should override the operator == operator as well to maintain consistency.
Inherited from Object.
Implementation
dart
external int get hashCode;isAbsolute no setter inherited
bool get isAbsoluteWhether this object's path is absolute.
An absolute path is independent of the current working directory (Directory.current). A non-absolute path must be interpreted relative to the current working directory.
On Windows, a path is absolute if it starts with \\ (two backslashes or representing a UNC path) or with a drive letter between a and z (upper or lower case) followed by :\ or :/. This makes, for example, \file.ext a non-absolute path because it depends on the current drive letter.
On non-Windows, a path is absolute if it starts with /.
If the path is not absolute, use absolute to get an entity with an absolute path referencing the same object in the file system, if possible.
Inherited from FileSystemEntity.
Implementation
dart
bool get isAbsolute => _isAbsolute(path);parent no setter inherited
Directory get parentThe parent directory of this entity.
Inherited from FileSystemEntity.
Implementation
dart
Directory get parent => new Directory(parentOf(path));path no setter override
String get pathGets the path of this directory.
Implementation
dart
String get path;runtimeType no setter inherited
Type get runtimeTypeA representation of the runtime type of the object.
Inherited from Object.
Implementation
dart
external Type get runtimeType;uri no setter override
Uri get uriA 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 ('/').
Implementation
dart
Uri get uri;Methods
create()
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.
Implementation
dart
Future<Directory> create({bool recursive = false});createSync()
void createSync({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.
Implementation
dart
void createSync({bool recursive = false});createTemp()
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.
Implementation
dart
Future<Directory> createTemp([String? prefix]);createTempSync()
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.
Implementation
dart
Directory createTempSync([String? prefix]);delete() override
Future<FileSystemEntity> delete({bool recursive = false})Deletes this Directory.
If recursive is false:
- If path corresponds to an empty directory, then that directory is deleted. If path corresponds to a link, and that link resolves to a directory, then the link at path will be deleted. In all other cases, delete completes with a FileSystemException.
If recursive is true:
- The FileSystemEntity at path is deleted regardless of type. If path corresponds to a file or link, then that file or link is deleted. If path corresponds to a directory, then it and all sub-directories and files in those directories are deleted. Links are not followed when deleting recursively. Only the link is deleted, not its target. This behavior allows delete to be used to unconditionally delete any file system object.
If this Directory cannot be deleted, then delete completes with a FileSystemException.
Implementation
dart
Future<FileSystemEntity> delete({bool recursive = false});deleteSync() override
void deleteSync({bool recursive = false})Synchronously deletes this Directory.
If recursive is false:
- If path corresponds to an empty directory, then that directory is deleted. If path corresponds to a link, and that link resolves to a directory, then the link at path will be deleted. In all other cases, delete throws a FileSystemException.
If recursive is true:
- The FileSystemEntity at path is deleted regardless of type. If path corresponds to a file or link, then that file or link is deleted. If path corresponds to a directory, then it and all sub-directories and files in those directories are deleted. Links are not followed when deleting recursively. Only the link is deleted, not its target. This behavior allows delete to be used to unconditionally delete any file system object.
If this Directory cannot be deleted, then delete throws a FileSystemException.
Implementation
dart
void deleteSync({bool recursive = false});exists() inherited
Checks whether the file system entity with this path exists.
Returns a Future<bool> that completes with the result.
Since FileSystemEntity is abstract, every FileSystemEntity object is actually an instance of one of the subclasses File, Directory, and Link. Calling exists on an instance of one of these subclasses checks whether the object exists in the file system object exists and is of the correct type (file, directory, or link). To check whether a path points to an object on the file system, regardless of the object's type, use the type static method.
Inherited from FileSystemEntity.
Implementation
dart
Future<bool> exists();existsSync() inherited
bool existsSync()Synchronously checks whether the file system entity with this path exists.
Since FileSystemEntity is abstract, every FileSystemEntity object is actually an instance of one of the subclasses File, Directory, and Link. Calling existsSync on an instance of one of these subclasses checks whether the object exists in the file system object exists and is of the correct type (file, directory, or link). To check whether a path points to an object on the file system, regardless of the object's type, use the typeSync static method.
Inherited from FileSystemEntity.
Implementation
dart
bool existsSync();list()
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 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. The Stream will be in an arbitrary order and does not include the special entries '.' and '..'.
Implementation
dart
Stream<FileSystemEntity> list({
bool recursive = false,
bool followLinks = true,
});listSync()
List<FileSystemEntity> listSync({
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. The List will be in an arbitrary order and does not include the special entries '.' and '..'.
Implementation
dart
List<FileSystemEntity> listSync({
bool recursive = false,
bool followLinks = true,
});noSuchMethod() inherited
dynamic noSuchMethod(Invocation invocation)Invoked when a nonexistent method or property is accessed.
A dynamic member invocation can attempt to call a member which doesn't exist on the receiving object. Example:
dart
dynamic object = 1;
object.add(42); // Statically allowed, run-time errorThis invalid code will invoke the noSuchMethod method of the integer 1 with an Invocation representing the .add(42) call and arguments (which then throws).
Classes can override noSuchMethod to provide custom behavior for such invalid dynamic invocations.
A class with a non-default noSuchMethod invocation can also omit implementations for members of its interface. Example:
dart
class MockList<T> implements List<T> {
noSuchMethod(Invocation invocation) {
log(invocation);
super.noSuchMethod(invocation); // Will throw.
}
}
void main() {
MockList().add(42);
}This code has no compile-time warnings or errors even though the MockList class has no concrete implementation of any of the List interface methods. Calls to List methods are forwarded to noSuchMethod, so this code will log an invocation similar to Invocation.method(#add, [42]) and then throw.
If a value is returned from noSuchMethod, it becomes the result of the original invocation. If the value is not of a type that can be returned by the original invocation, a type error occurs at the invocation.
The default behavior is to throw a NoSuchMethodError.
Inherited from Object.
Implementation
dart
@pragma("vm:entry-point")
@pragma("wasm:entry-point")
external dynamic noSuchMethod(Invocation invocation);rename() override
Renames this directory.
Returns a Future<Directory> that completes with a Directory for the renamed directory.
If newPath identifies an existing directory, then the behavior is platform-specific. On all platforms, the future completes with a FileSystemException if the existing directory is not empty. On POSIX systems, if newPath identifies an existing empty directory then that directory is deleted before this directory is renamed.
If newPath identifies an existing file or link, the operation fails and the future completes with a FileSystemException.
Implementation
dart
Future<Directory> rename(String newPath);renameSync() override
Synchronously renames this directory.
Returns a Directory for the renamed directory.
If newPath identifies an existing directory, then the behavior is platform-specific. On all platforms, a FileSystemException is thrown if the existing directory is not empty. On POSIX systems, if newPath identifies an existing empty directory then that directory is deleted before this directory is renamed.
If newPath identifies an existing file or link the operation fails and a FileSystemException is thrown.
Implementation
dart
Directory renameSync(String newPath);resolveSymbolicLinks() override
Resolves the path of a file system object relative to the current working directory.
Resolves all symbolic links on the path and resolves all .. and . path segments.
resolveSymbolicLinks uses the operating system's native file system API to resolve the path, using the realpath function on Linux and OS X, and the GetFinalPathNameByHandle function on Windows. If the path does not point to an existing file system object, resolveSymbolicLinks throws a FileSystemException.
On Windows the .. segments are resolved before resolving the symbolic link, and on other platforms the symbolic links are resolved to their target before applying a .. that follows.
To ensure the same behavior on all platforms resolve .. segments before calling resolveSymbolicLinks. One way of doing this is with the Uri class:
dart
var path = Uri.parse('.').resolveUri(Uri.file(input)).toFilePath();
if (path == '') path = '.';
var resolved = await File(path).resolveSymbolicLinks();
print(resolved);since Uri.resolve removes .. segments. This will result in the Windows behavior.
On Windows, attempting to resolve a symbolic link where the link type does not match the type of the resolved file system object will cause the Future to complete with a PathAccessException error.
Implementation
dart
Future<String> resolveSymbolicLinks();resolveSymbolicLinksSync() override
String resolveSymbolicLinksSync()Resolves the path of a file system object relative to the current working directory.
Resolves all symbolic links on the path and resolves all .. and . path segments.
resolveSymbolicLinksSync uses the operating system's native file system API to resolve the path, using the realpath function on linux and OS X, and the GetFinalPathNameByHandle function on Windows. If the path does not point to an existing file system object, resolveSymbolicLinksSync throws a FileSystemException.
On Windows the .. segments are resolved before resolving the symbolic link, and on other platforms the symbolic links are resolved to their target before applying a .. that follows.
To ensure the same behavior on all platforms resolve .. segments before calling resolveSymbolicLinksSync. One way of doing this is with the Uri class:
dart
var path = Uri.parse('.').resolveUri(Uri.file(input)).toFilePath();
if (path == '') path = '.';
var resolved = File(path).resolveSymbolicLinksSync();
print(resolved);since Uri.resolve removes .. segments. This will result in the Windows behavior.
On Windows, a symbolic link is created as either a file link or a directory link. Attempting to resolve such a symbolic link requires the link type to match the type of the file system object that it points to, otherwise it throws a PathAccessException.
Implementation
dart
String resolveSymbolicLinksSync();stat() inherited
Calls the operating system's stat() function on path.
Identical to FileStat.stat(this.path).
Returns a Future<FileStat> object containing the data returned by stat().
If path is a symbolic link then it is resolved and results for the resulting file are returned.
If the call fails, completes the future with a FileStat object with .type set to FileSystemEntityType.notFound and the other fields invalid.
Inherited from FileSystemEntity.
Implementation
dart
Future<FileStat> stat() => FileStat.stat(path);statSync() inherited
FileStat statSync()Synchronously calls the operating system's stat() function on path.
Identical to FileStat.statSync(this.path).
Returns a FileStat object containing the data returned by stat().
If path is a symbolic link then it is resolved and results for the resulting file are returned.
If the call fails, returns a FileStat object with .type set to FileSystemEntityType.notFound and the other fields invalid.
Inherited from FileSystemEntity.
Implementation
dart
FileStat statSync() => FileStat.statSync(path);toString() override
String toString()Returns a human readable representation of this Directory.
Implementation
dart
String toString();watch() inherited
Stream<FileSystemEvent> watch({
int events = FileSystemEvent.all,
bool recursive = false,
})Start watching the FileSystemEntity for changes.
The implementation uses platform-dependent event-based APIs for receiving file-system notifications, thus behavior depends on the platform.
Windows: UsesReadDirectoryChangesW. The implementation only supports watching directories. Recursive watching is supported.Linux: Usesinotify. The implementation supports watching both files and directories. Recursive watching is not supported. Note: When watching files directly, delete events might not happen as expected.OS X: Uses the File System Events API. The implementation supports watching both files and directories. Recursive watching is supported. This API has several limitations:- Changes that occurred shortly before the watch method was called may still appear in the Stream.
- Changes that occur in a short period of time may arrive out-of-order.
- Multiple changes made in a single directory may be coalesced into a single
FileSystemEvent.
The system will start listening for events once the returned Stream is being listened to, not when the call to watch is issued.
The returned value is an endless broadcast Stream, that only stops when one of the following happens:
- The Stream is canceled, e.g. by calling
cancelon the StreamSubscription. - The FileSystemEntity being watched is deleted.
- System Watcher exits unexpectedly. e.g. On
Windowsthis happens when buffer that receive events fromReadDirectoryChangesWoverflows.
Use events to specify what events to listen for. The constants in FileSystemEvent can be or'ed together to mix events. Default is FileSystemEvent.all.
A move event may be reported as separate delete and create events.
Inherited from FileSystemEntity.
Implementation
dart
Stream<FileSystemEvent> watch({
int events = FileSystemEvent.all,
bool recursive = false,
}) {
// FIXME(bkonyi): find a way to do this using the raw path.
final String trimmedPath = _trimTrailingPathSeparators(path);
final IOOverrides? overrides = IOOverrides.current;
if (overrides == null) {
return _FileSystemWatcher._watch(trimmedPath, events, recursive);
}
return overrides.fsWatch(trimmedPath, events, recursive);
}Operators
operator ==() inherited
The equality operator.
The default behavior for all Objects is to return true if and only if this object and other are the same object.
Override this method to specify a different equality relation on a class. The overriding method must still be an equivalence relation. That is, it must be:
Total: It must return a boolean for all arguments. It should never throw.
Reflexive: For all objects
o,o == omust be true.Symmetric: For all objects
o1ando2,o1 == o2ando2 == o1must either both be true, or both be false.Transitive: For all objects
o1,o2, ando3, ifo1 == o2ando2 == o3are true, theno1 == o3must be true.
The method should also be consistent over time, so whether two objects are equal should only change if at least one of the objects was modified.
If a subclass overrides the equality operator, it should override the hashCode method as well to maintain consistency.
Inherited from Object.
Implementation
dart
external bool operator ==(Object other);Static Properties
current read / write
Directory get currentgetter:
Creates a directory object pointing to the current working directory.
setter:
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.
Implementation
dart
static Directory get current {
final IOOverrides? overrides = IOOverrides.current;
if (overrides == null) {
return _Directory.current;
}
return overrides.getCurrentDirectory();
}
static void set current(dynamic path) {
// Disallow implicit casts to avoid bugs like
// <https://github.com/dart-lang/sdk/issues/52140>.
//
// This can be removed if `strict-casts` is enabled.
path as Object?;
final IOOverrides? overrides = IOOverrides.current;
if (overrides == null) {
_Directory.current = path;
return;
}
// IOOverrides.setCurrentDirectory accepts only a [String].
overrides.setCurrentDirectory(switch (path) {
String s => s,
Directory d => d.path,
_ => throw ArgumentError(
'${Error.safeToString(path)} is not a String or'
' Directory',
),
});
}systemTemp no setter
Directory get systemTempThe 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.
Implementation
dart
static Directory get systemTemp {
final IOOverrides? overrides = IOOverrides.current;
if (overrides == null) {
return _Directory.systemTemp;
}
return overrides.getSystemTempDirectory();
}