Dart Link
last modified October 18, 2026
The Link class in Dart provides a way to work with symbolic links
on the file system. It is part of the dart:io library for
server-side and command-line applications.
A Link represents a symbolic link: a directory entry that points to
another path. It allows creating, inspecting, updating, and deleting links
programmatically.
Basic Definition
Link is a concrete FileSystemEntity that represents a
symbolic link. It inherits the common entity operations such as
exists(), delete(), stat(), and
watch().
Key features include creating a link to a target path, reading the target with
target(), replacing the target with update(), and
removing the link without affecting its target. The Link class does
not read or write file contents; use a File for that.
Creating a Symbolic Link
This example shows how to create a symbolic link to an existing file.
import 'dart:io';
void main() async {
var target = File('target.txt');
await target.writeAsString('Hello from the target file\n');
var link = Link('link.txt');
await link.create(target.path);
print('Created link: ${link.path}');
print('Link target: ${await link.target()}');
print(await File(link.path).readAsString());
await link.delete();
await target.delete();
}
We write a target file and create a Link that points to it. The
target() method returns the path stored in the link, and reading
the link path through a File follows the link to the target.
$ dart main.dart Created link: link.txt Link target: target.txt Hello from the target file
Reading a Link Target
This example demonstrates checking a link and reading the path it points to.
import 'dart:io';
void main() async {
var target = File('target.txt');
await target.writeAsString('data');
var link = Link('link.txt');
await link.create(target.path);
print('Link exists: ${await link.exists()}');
print('Points to: ${await link.target()}');
await link.delete();
await target.delete();
}
Link.exists() checks for the link itself, while
target() returns the target path exactly as it was stored when the
link was created.
$ dart main.dart Link exists: true Points to: target.txt
Updating a Link
This example shows how to point an existing link at a different target.
import 'dart:io';
void main() async {
var first = File('first.txt');
var second = File('second.txt');
await first.writeAsString('first');
await second.writeAsString('second');
var link = Link('current.txt');
await link.create(first.path);
print('Initially: ${await link.target()}');
await link.update(second.path);
print('After update: ${await link.target()}');
print(await File(link.path).readAsString());
await link.delete();
await first.delete();
await second.delete();
}
update() deletes the existing link and recreates it with the new
target path. The target files themselves are not modified.
$ dart main.dart Initially: first.txt After update: second.txt second
Checking Link Type
This example demonstrates distinguishing a symbolic link from its target.
import 'dart:io';
void main() async {
var target = File('target.txt');
await target.writeAsString('target content');
var link = Link('link.txt');
await link.create(target.path);
var linkType = await FileSystemEntity.type(link.path, followLinks: false);
var targetType = await FileSystemEntity.type(link.path);
print('Link type: $linkType');
print('Target type: $targetType');
await link.delete();
await target.delete();
}
By default FileSystemEntity.type() follows links and reports the
target's type. Passing followLinks: false reports
FileSystemEntityType.link for the link itself.
$ dart main.dart Link type: link Target type: file
Creating Multiple Links
This example shows how to create several links in a loop.
import 'dart:io';
void main() async {
var targets = {
'readme.txt': 'Read me first',
'config.json': '{"debug": false}',
};
for (var entry in targets.entries) {
await File(entry.key).writeAsString(entry.value);
}
var links = <String, Link>{};
for (var name in targets.keys) {
var link = Link('link_$name');
await link.create(name);
links[name] = link;
}
for (var entry in links.entries) {
print('${entry.value.path} -> ${await entry.value.target()}');
}
for (var link in links.values) {
await link.delete();
}
for (var name in targets.keys) {
await File(name).delete();
}
}
Each link maps a separate name to an existing target file. After printing the mappings, the links are removed first and then the target files are deleted.
$ dart main.dart link_readme.txt -> readme.txt link_config.json -> config.json
Deleting a Link
This example shows that deleting a link leaves its target untouched.
import 'dart:io';
void main() async {
var target = File('target.txt');
await target.writeAsString('keep me');
var link = Link('link.txt');
await link.create(target.path);
await link.delete();
print('Link exists: ${await link.exists()}');
print('Target exists: ${await target.exists()}');
await target.delete();
}
Deleting a Link removes only the directory entry, not the target
file. The target remains available at its original path.
$ dart main.dart Link exists: false Target exists: true
Best Practices
- Use target(): Read the stored target path with
link.target(); it may be relative. - Detect links explicitly: Use
FileSystemEntity.type(path, followLinks: false)to avoid following the link. - Delete the link first: Remove links before their targets when cleaning up temporary data.
- Clean up: Delete temporary links and target files when done.
- Cross-platform: Creating symbolic links on Windows may require developer mode or elevated privileges.
Source
This tutorial covered Dart's Link class with practical examples showing symbolic link creation, target inspection, updates, type checks, and deletion.
Author
List all Dart tutorials.