Watch the video (9 min)
On this page25 sections
  1. Prerequisites
  2. Connection With Previous Lectures
  3. Learning Objectives
  4. 1. What Are Directories and Paths?
  5. 2. Where Am I? — Directory.current
  6. 3. Relative vs Absolute Paths
  7. 4. The Path Separator
  8. 5. A Safe Playground — Temporary Directories
  9. 6. Creating a Directory
  10. 7. Nested Folders — recursive: true
  11. 8. Listing a Directory — list()
  12. 9. listSync() and recursive: true
  13. 10. File or Folder? — FileSystemEntity
  14. 11. Building Paths Safely — package:path
  15. 12. Deleting a Directory
  16. 13. A Real-World Example
  17. Code Examples
  18. Common Beginner Mistakes
  19. Best Practices
  20. Mini Challenge
  21. Practice Questions
  22. Practice Answers
  23. Quick Revision
  24. Key Takeaways
  25. What's Next?

Lecture 107 — Directories & Paths

Category18 — Files, JSON & Core Utilities
Lecture107 of 140
Estimated video length9 min
TargetDart 3.12.2
LevelIntermediate

In Lecture 106 every file landed in one place, and 'notes.txt' was somewhere we never checked. Directories let a program build folders, look inside them and clean them up — and paths tell it exactly where everything lives.

Contents

Prerequisites · Connection · Objectives · Lesson · Code Examples · Common Mistakes · Best Practices · Mini Challenge · Practice Questions · Answers · Takeaways

Every output and error message in this lecture is real, produced on Dart 3.12.2 on macOS. Full paths differ on every computer, so they are shown as placeholders: <project> is the folder you run the program from, and <temp> is a temporary folder Dart creates (its name ends in random letters). On Windows you will see \ instead of /.


Prerequisites

Students should already understand, from Lectures 089–106:

  • async/await and Future<void> main() async (Lecture 089)
  • try/catch around an await (Lecture 090)
  • await for over a stream (Lecture 092)
  • import ... as prefixes (Lecture 101)
  • adding a package to pubspec.yaml (Lectures 104–105)
  • dart:io, File, writeAsString, readAsString, exists and delete (Lecture 106)

Connection With Previous Lectures

In Lecture 106, Ali saved marks like this:

dart
import 'dart:io';

Future<void> main() async {
  await File('ali.txt').writeAsString('Ali: 80');
}

It works, but two questions remain. Where is ali.txt on the disk? And with 300 students, how do we put the files into a reports folder, list them, and delete them later? A File cannot answer those. A Directory and a correct path can.


Learning Objectives

By the end of this lecture you will be able to:

  • Understand what a directory and a path are
  • Find the working directory with Directory.current
  • Tell relative paths from absolute paths
  • Use Platform.pathSeparator and package:path to build paths safely
  • Create a safe playground with Directory.systemTemp.createTemp
  • Create nested folders with create(recursive: true)
  • List a folder with list() and listSync(), and tell files from folders
  • Delete a folder, including one that is not empty

1. What Are Directories and Paths?

A directory (folder) holds files and other directories. A path is the text that says where something is.

Analogy — a path is a street address. reports/2026/ali.txt means: go to the reports building, then floor 2026, then the door labelled ali.txt.

In Dart, folders come from dart:io as Directory objects, just as files are File objects.


2. Where Am I? — Directory.current

Every running program has a working directory: the folder it was started from.

dart
import 'dart:io';

void main() {
  print(Directory.current.path);
}
output
<project>

When you run dart run inside your project folder, this prints that folder's full path.


3. Relative vs Absolute Paths

An absolute path starts at the top of the disk (/ on macOS and Linux, a drive like C:\ on Windows). A relative path is measured from the working directory.

dart
import 'dart:io';

void main() {
  File relative = File('notes.txt');
  print(relative.path);
  print(relative.isAbsolute);
  print(relative.absolute.path);
  print(relative.absolute.isAbsolute);
}
output
notes.txt
false
<project>/notes.txt
true

That answers the Connection question: Lecture 106's ali.txt was written into the working directory. Run the program from another folder and the file goes there instead.


4. The Path Separator

macOS and Linux separate folder names with /; Windows uses \. Platform.pathSeparator gives the right one for the computer the program is running on.

dart
import 'dart:io';

void main() {
  print(Platform.pathSeparator);
  print(Platform.operatingSystem);
}
output
/
macos

On Windows the same program prints \ and windows.


5. A Safe Playground — Temporary Directories

Practising delete on real folders is risky. Directory.systemTemp is the operating system's temporary folder, and createTemp makes a brand-new, empty folder inside it with a unique name.

dart
import 'dart:io';

Future<void> main() async {
  Directory temp = await Directory.systemTemp.createTemp('lesson_');
  print(temp.path);
  print(await temp.exists());
  await temp.delete();
  print(await temp.exists());
}
output
<temp>/lesson_rXVLa9
true
false

The letters after lesson_ are random, so yours will differ. Every demo below works inside such a folder and deletes it at the end.


6. Creating a Directory

create() makes the folder. exists() checks for it, just like on a File.

dart
import 'dart:io';

Future<void> main() async {
  Directory temp = await Directory.systemTemp.createTemp('lesson_');
  String sep = Platform.pathSeparator;

  Directory reports = Directory('${temp.path}${sep}reports');
  await reports.create();
  print(await reports.exists());

  await temp.delete(recursive: true);
}
output
true

Each async method also has a Sync twin — createSync(), existsSync(), deleteSync() — as you saw for files in Lecture 106.


7. Nested Folders — recursive: true

Plain create() makes only the last folder; every parent must already exist. recursive: true creates all missing parents, and does nothing if the folder is already there.

dart
import 'dart:io';

Future<void> main() async {
  Directory temp = await Directory.systemTemp.createTemp('lesson_');
  String sep = Platform.pathSeparator;

  Directory deep = Directory('${temp.path}${sep}2026${sep}march${sep}week1');
  await deep.create(recursive: true);
  print(await deep.exists());

  await deep.create(recursive: true); // already there — no error
  print('Still fine');

  await temp.delete(recursive: true);
}
output
true
Still fine

Without recursive: true, the same create() fails — see Common Mistakes.


8. Listing a Directory — list()

list() returns a Stream<FileSystemEntity>: one item per file or folder inside. Read it with await for.

dart
import 'dart:io';

Future<void> main() async {
  Directory temp = await Directory.systemTemp.createTemp('lesson_');
  String sep = Platform.pathSeparator;

  await File('${temp.path}${sep}ali.txt').writeAsString('Ali: 80');
  await File('${temp.path}${sep}sara.txt').writeAsString('Sara: 92');
  await Directory('${temp.path}${sep}archive').create();

  await for (FileSystemEntity entity in temp.list()) {
    print(entity.path.split(sep).last);
  }

  await temp.delete(recursive: true);
}
output
sara.txt
archive
ali.txt

The order is not guaranteed — it depends on the operating system. Sort when order matters.


9. listSync() and recursive: true

listSync() returns a plain List<FileSystemEntity> at once. With recursive: true, both versions also look inside every sub-folder.

dart
import 'dart:io';

Future<void> main() async {
  Directory temp = await Directory.systemTemp.createTemp('lesson_');
  String sep = Platform.pathSeparator;

  await File('${temp.path}${sep}ali.txt').writeAsString('Ali: 80');
  await Directory('${temp.path}${sep}archive').create();
  await File('${temp.path}${sep}archive${sep}old.txt').writeAsString('old');

  List<FileSystemEntity> top = temp.listSync();
  List<FileSystemEntity> all = temp.listSync(recursive: true);
  print('Top level: ${top.length}');
  print('Everything: ${all.length}');

  await temp.delete(recursive: true);
}
output
Top level: 2
Everything: 3

The top level holds ali.txt and archive; recursion adds archive/old.txt.


10. File or Folder? — FileSystemEntity

FileSystemEntity is the parent class of File, Directory and Link (a shortcut to another path). Use is to find out which one you have.

dart
import 'dart:io';

Future<void> main() async {
  Directory temp = await Directory.systemTemp.createTemp('lesson_');
  String sep = Platform.pathSeparator;

  await File('${temp.path}${sep}ali.txt').writeAsString('Ali: 80');
  await Directory('${temp.path}${sep}archive').create();

  List<FileSystemEntity> entries = temp.listSync();
  entries.sort((a, b) => a.path.compareTo(b.path));

  for (FileSystemEntity entity in entries) {
    String name = entity.path.split(sep).last;
    if (entity is File) {
      print('File:   $name');
    } else if (entity is Directory) {
      print('Folder: $name');
    }
  }

  await temp.delete(recursive: true);
}
output
File:   ali.txt
Folder: archive

For a bare path string, FileSystemEntity.type answers the same question — including "nothing there":

dart
import 'dart:io';

Future<void> main() async {
  Directory temp = await Directory.systemTemp.createTemp('lesson_');
  String sep = Platform.pathSeparator;
  await File('${temp.path}${sep}ali.txt').writeAsString('Ali: 80');

  print(await FileSystemEntity.type('${temp.path}${sep}ali.txt'));
  print(await FileSystemEntity.type(temp.path));
  print(await FileSystemEntity.type('${temp.path}${sep}missing.txt'));

  await temp.delete(recursive: true);
}
output
file
directory
notFound

11. Building Paths Safely — package:path

Gluing strings with Platform.pathSeparator works, but it is noisy and easy to get wrong. The official path package does it for you. Add it as in Lecture 105 (dart pub add path), then import it with a prefix:

dart
import 'package:path/path.dart' as p;

void main() {
  String file = p.join('reports', '2026', 'ali.txt');
  print(file);
  print(p.basename(file));
  print(p.basenameWithoutExtension(file));
  print(p.extension(file));
  print(p.dirname(file));
  print(p.isAbsolute(file));
}
output
reports/2026/ali.txt
ali.txt
ali
.txt
reports/2026
false

p.join uses the correct separator for the platform and never doubles or forgets one. The as p prefix is the convention, because names like join and extension are too common to import bare.


12. Deleting a Directory

delete() refuses a folder that still has something inside. delete(recursive: true) removes the folder and everything in it.

dart
import 'dart:io';

Future<void> main() async {
  Directory temp = await Directory.systemTemp.createTemp('lesson_');
  String sep = Platform.pathSeparator;
  await File('${temp.path}${sep}ali.txt').writeAsString('Ali: 80');

  await temp.delete(recursive: true);
  print(await temp.exists());
}
output
false

There is no recycle bin. Only use recursive: true on a path you are certain about.


13. A Real-World Example

Sara's school keeps one folder per class. The program builds the folders, saves one report per student, then lists them in order.

dart
import 'dart:io';

import 'package:path/path.dart' as p;

Future<void> main() async {
  Directory temp = await Directory.systemTemp.createTemp('school_');
  Map<String, int> classA = {'Ali': 80, 'Sara': 92};

  Directory folder = Directory(p.join(temp.path, 'reports', 'class_a'));
  await folder.create(recursive: true);

  for (MapEntry<String, int> entry in classA.entries) {
    File file = File(p.join(folder.path, '${entry.key.toLowerCase()}.txt'));
    await file.writeAsString('${entry.key}: ${entry.value}');
  }

  List<File> files = folder.listSync().whereType<File>().toList();
  files.sort((a, b) => a.path.compareTo(b.path));
  for (File file in files) {
    print('${p.basename(file.path)} -> ${await file.readAsString()}');
  }

  await temp.delete(recursive: true);
}
output
ali.txt -> Ali: 80
sara.txt -> Sara: 92

Create the folders, build each path with p.join, write, list, sort, clean up.


Code Examples

The examples from 6 onwards use package:path, so run them in a project that depends on it.

Example 1 — Working Directory

dart
import 'dart:io';

void main() {
  print(Directory.current.isAbsolute);
  print(Directory('data').isAbsolute);
}
output
true
false

Example 2 — Making a Path Absolute

dart
import 'dart:io';

void main() {
  Directory data = Directory('data');
  print(data.path);
  print(data.absolute.path);
}
output
data
<project>/data

Example 3 — Synchronous Playground

dart
import 'dart:io';

void main() {
  Directory temp = Directory.systemTemp.createTempSync('sync_');
  print(temp.existsSync());
  temp.deleteSync();
  print(temp.existsSync());
}
output
true
false

Example 4 — Nested Folders, Synchronously

dart
import 'dart:io';

void main() {
  Directory temp = Directory.systemTemp.createTempSync('nest_');
  String sep = Platform.pathSeparator;
  Directory deep = Directory('${temp.path}${sep}a${sep}b${sep}c');
  deep.createSync(recursive: true);
  print(deep.existsSync());
  temp.deleteSync(recursive: true);
}
output
true

Example 5 — Counting Only Files

dart
import 'dart:io';

void main() {
  Directory temp = Directory.systemTemp.createTempSync('count_');
  String sep = Platform.pathSeparator;
  File('${temp.path}${sep}one.txt').writeAsStringSync('1');
  File('${temp.path}${sep}two.txt').writeAsStringSync('2');
  Directory('${temp.path}${sep}sub').createSync();

  int files = temp.listSync().whereType<File>().length;
  print('Files: $files');
  temp.deleteSync(recursive: true);
}
output
Files: 2

Example 6 — Taking a Path Apart

dart
import 'package:path/path.dart' as p;

void main() {
  print(p.split('reports/2026/ali.txt'));
  print(p.join('reports/', 'ali.txt'));
  print(p.relative('/school/reports/ali.txt', from: '/school'));
}
output
[reports, 2026, ali.txt]
reports/ali.txt
reports/ali.txt

p.join notices the trailing / on 'reports/' and does not add a second one.

Example 7 — Student Report Folders

dart
import 'dart:io';

import 'package:path/path.dart' as p;

void main() {
  Directory temp = Directory.systemTemp.createTempSync('students_');
  for (String name in ['Zayan', 'Ali', 'Sara']) {
    Directory(p.join(temp.path, name)).createSync();
  }

  List<String> names = temp
      .listSync()
      .map((entity) => p.basename(entity.path))
      .toList();
  names.sort();
  print(names);
  temp.deleteSync(recursive: true);
}
output
[Ali, Sara, Zayan]

Example 8 — Shopping Receipts Total

dart
import 'dart:io';

import 'package:path/path.dart' as p;

Future<void> main() async {
  Directory temp = await Directory.systemTemp.createTemp('receipts_');
  Map<String, int> receipts = {'monday': 450, 'tuesday': 1200, 'friday': 300};
  for (MapEntry<String, int> r in receipts.entries) {
    await File(p.join(temp.path, '${r.key}.txt')).writeAsString('${r.value}');
  }

  int total = 0;
  await for (FileSystemEntity entity in temp.list()) {
    if (entity is File) {
      total += int.parse(await entity.readAsString());
    }
  }
  print('Total spent: $total');
  await temp.delete(recursive: true);
}
output
Total spent: 1950

The list() order does not matter here, because addition gives the same total in any order.

Example 9 — Bank Statements by Year

dart
import 'dart:io';

import 'package:path/path.dart' as p;

void main() {
  Directory temp = Directory.systemTemp.createTempSync('bank_');
  for (String year in ['2025', '2026']) {
    String folder = p.join(temp.path, 'statements', year);
    Directory(folder).createSync(recursive: true);
    File(p.join(folder, 'jan.txt')).writeAsStringSync('1000');
  }

  List<FileSystemEntity> all = temp.listSync(recursive: true);
  print('Folders: ${all.whereType<Directory>().length}');
  print('Files: ${all.whereType<File>().length}');
  temp.deleteSync(recursive: true);
}
output
Folders: 3
Files: 2

The three folders are statements, statements/2025 and statements/2026.

Example 10 — Cleaning Old Temperature Logs

dart
import 'dart:io';

import 'package:path/path.dart' as p;

void main() {
  Directory temp = Directory.systemTemp.createTempSync('logs_');
  for (String name in ['monday.log', 'monday.tmp', 'tuesday.tmp']) {
    File(p.join(temp.path, name)).writeAsStringSync('25.0');
  }

  for (File file in temp.listSync().whereType<File>()) {
    if (p.extension(file.path) == '.tmp') {
      file.deleteSync();
    }
  }

  List<String> left = temp
      .listSync()
      .map((entity) => p.basename(entity.path))
      .toList();
  print(left);
  temp.deleteSync(recursive: true);
}
output
[monday.log]

Common Beginner Mistakes

1. Creating a nested folder without recursive: true

dart
// Directory('${temp.path}${sep}2026${sep}march${sep}week1').create(); // ✗
output
PathNotFoundException: Creation failed, path = '<temp>/lesson_Mw7tAF/2026/march/week1' (OS Error: No such file or directory, errno = 2)

2026 and march did not exist yet. Add recursive: true.

2. Deleting a folder that is not empty

dart
// await temp.delete(); // ✗ temp still contains ali.txt
output
FileSystemException: Deletion failed, path = '<temp>/lesson_w7LRLE' (OS Error: Directory not empty, errno = 66)

Use delete(recursive: true) — after double-checking the path.

3. Forgetting the separator when joining strings

dart
String folder = 'reports';
print('${folder}ali.txt'); // ✗ no separator
output
reportsali.txt

p.join(folder, 'ali.txt') gives reports/ali.txt.

4. Hard-coding / or \

'reports/ali.txt' happens to work on macOS and Linux. Use p.join or Platform.pathSeparator so the same code is correct on Windows.

5. Expecting list() to be alphabetical

The order comes from the operating system. Sort the results when order matters.

6. Assuming a relative path is next to your .dart file

A relative path is measured from Directory.current — where the program was started, not where its source file lives.


Best Practices

  • Experiment inside Directory.systemTemp.createTemp(...), and delete it when done.
  • Build paths with p.join; read their parts with p.basename, p.extension, p.dirname.
  • Use create(recursive: true) when parent folders might be missing.
  • Treat delete(recursive: true) like a power tool: only on paths you built yourself.
  • Sort listings before showing them to people.
  • Prefer the async methods in programs that do other work; Sync versions are fine for short scripts.

Mini Challenge

Inside a temporary folder, create backup/2026 and backup/2025 in one go each, put a file notes.txt into backup/2026, then print every entry under backup, sorted, as a path relative to the temporary folder.

Your program should print exactly:

output
backup/2025
backup/2026
backup/2026/notes.txt

Try it yourself before opening the solution.

Show solution
dart
import 'dart:io';

import 'package:path/path.dart' as p;

void main() {
  Directory temp = Directory.systemTemp.createTempSync('backup_');
  String backup = p.join(temp.path, 'backup');
  Directory(p.join(backup, '2026')).createSync(recursive: true);
  Directory(p.join(backup, '2025')).createSync(recursive: true);
  File(p.join(backup, '2026', 'notes.txt')).writeAsStringSync('hi');

  List<String> paths = Directory(backup)
      .listSync(recursive: true)
      .map((entity) => p.relative(entity.path, from: temp.path))
      .toList();
  paths.sort();
  paths.forEach(print);
  temp.deleteSync(recursive: true);
}
output
backup/2025
backup/2026
backup/2026/notes.txt

p.relative strips the random temporary folder from the front, so the output is the same on every run.


Practice Questions

Work through these in order — they run from beginner to application to challenge. Use a temporary folder whenever you create something.

Beginner

  1. Print whether Directory.current is an absolute path.
  2. Print whether File('marks.txt') is an absolute path.
  3. Use p.join to build school/class1/ali.txt, then print its basename and its extension.

Application

  1. Create a temporary folder quiz_, create a/b/c inside it in one call, print whether c exists, then clean up.
  2. Write ali.txt, sara.txt and zayan.txt into a temporary folder and print Count: 3 using listSync().
  3. In a temporary folder, create a file marks.txt and a folder old. Print each entry, sorted, as File: marks.txt or Folder: old.
  4. Print the FileSystemEntity.type of a path that does not exist.
  5. Put a file in a temporary folder, then call delete() without recursive inside try/catch. On FileSystemException, print Not empty — deleting everything and delete recursively. Finally print whether the folder exists.

Challenge

  1. In a temporary folder, create a.txt, b.log and sub/c.txt. Count all .txt files, including those in sub-folders, and print Text files: 2.
  2. Write Future<int> folderSize(Directory dir) that adds up await file.length() (the size in bytes) for every file, recursively. Test it with ali.txt holding Ali: 80 and sub/sara.txt holding Sara: 92.

Practice Answers

Question 1 — Solution

dart
import 'dart:io';

void main() {
  print(Directory.current.isAbsolute);
}
output
true

Question 2 — Solution

dart
import 'dart:io';

void main() {
  print(File('marks.txt').isAbsolute);
}
output
false

Question 3 — Solution

dart
import 'package:path/path.dart' as p;

void main() {
  String path = p.join('school', 'class1', 'ali.txt');
  print(p.basename(path));
  print(p.extension(path));
}
output
ali.txt
.txt

Question 4 — Solution

dart
import 'dart:io';

import 'package:path/path.dart' as p;

Future<void> main() async {
  Directory temp = await Directory.systemTemp.createTemp('quiz_');
  Directory c = Directory(p.join(temp.path, 'a', 'b', 'c'));
  await c.create(recursive: true);
  print(await c.exists());
  await temp.delete(recursive: true);
}
output
true

Question 5 — Solution

dart
import 'dart:io';

import 'package:path/path.dart' as p;

void main() {
  Directory temp = Directory.systemTemp.createTempSync('count_');
  for (String name in ['ali', 'sara', 'zayan']) {
    File(p.join(temp.path, '$name.txt')).writeAsStringSync(name);
  }
  print('Count: ${temp.listSync().length}');
  temp.deleteSync(recursive: true);
}
output
Count: 3

Question 6 — Solution

dart
import 'dart:io';

import 'package:path/path.dart' as p;

void main() {
  Directory temp = Directory.systemTemp.createTempSync('kinds_');
  File(p.join(temp.path, 'marks.txt')).writeAsStringSync('80');
  Directory(p.join(temp.path, 'old')).createSync();

  List<FileSystemEntity> entries = temp.listSync();
  entries.sort((a, b) => a.path.compareTo(b.path));
  for (FileSystemEntity entity in entries) {
    String label = entity is File ? 'File' : 'Folder';
    print('$label: ${p.basename(entity.path)}');
  }
  temp.deleteSync(recursive: true);
}
output
File: marks.txt
Folder: old

Question 7 — Solution

dart
import 'dart:io';

Future<void> main() async {
  print(await FileSystemEntity.type('no_such_folder'));
}
output
notFound

Question 8 — Solution

dart
import 'dart:io';

import 'package:path/path.dart' as p;

Future<void> main() async {
  Directory temp = await Directory.systemTemp.createTemp('full_');
  await File(p.join(temp.path, 'ali.txt')).writeAsString('Ali: 80');

  try {
    await temp.delete();
  } on FileSystemException {
    print('Not empty — deleting everything');
    await temp.delete(recursive: true);
  }
  print(await temp.exists());
}
output
Not empty — deleting everything
false

Question 9 — Solution

dart
import 'dart:io';

import 'package:path/path.dart' as p;

void main() {
  Directory temp = Directory.systemTemp.createTempSync('txt_');
  Directory(p.join(temp.path, 'sub')).createSync();
  for (String name in ['a.txt', 'b.log', p.join('sub', 'c.txt')]) {
    File(p.join(temp.path, name)).writeAsStringSync('x');
  }

  int count = temp
      .listSync(recursive: true)
      .whereType<File>()
      .where((file) => p.extension(file.path) == '.txt')
      .length;
  print('Text files: $count');
  temp.deleteSync(recursive: true);
}
output
Text files: 2

Question 10 — Solution

dart
import 'dart:io';

import 'package:path/path.dart' as p;

Future<int> folderSize(Directory dir) async {
  int total = 0;
  await for (FileSystemEntity entity in dir.list(recursive: true)) {
    if (entity is File) {
      total += await entity.length();
    }
  }
  return total;
}

Future<void> main() async {
  Directory temp = await Directory.systemTemp.createTemp('size_');
  await Directory(p.join(temp.path, 'sub')).create();
  await File(p.join(temp.path, 'ali.txt')).writeAsString('Ali: 80');
  await File(p.join(temp.path, 'sub', 'sara.txt')).writeAsString('Sara: 92');

  print('Size: ${await folderSize(temp)} bytes');
  await temp.delete(recursive: true);
}
output
Size: 15 bytes

'Ali: 80' is 7 bytes and 'Sara: 92' is 8, so the total is 15.


Quick Revision

  1. What is the difference between a relative and an absolute path?
  2. What does Directory.current tell you?
  3. What does Platform.pathSeparator return on Windows?
  4. Why practise inside Directory.systemTemp.createTemp?
  5. What does recursive: true change for create, list and delete?
  6. Is the order of list() guaranteed?
  7. How do you tell a File from a Directory in a listing?
  8. Why is p.join safer than gluing strings?

Key Takeaways

  • A path says where something is; a directory holds files and other directories.
  • Relative paths are measured from Directory.current, the folder the program started in.
  • Platform.pathSeparator is / on macOS and Linux and \ on Windows; p.join handles it for you.
  • Directory.systemTemp.createTemp('name_') gives a safe, unique playground folder.
  • create(recursive: true) builds missing parents; plain create() fails without them.
  • list() streams entries, listSync() returns a list; neither promises an order.
  • File, Directory and Link are all FileSystemEntity; test with is.
  • delete() fails on a non-empty folder; delete(recursive: true) removes everything.

What's Next?

Lecture 108 — JSON. Our files so far hold plain text like Ali: 80. Next we will store structured data — names, marks and lists together — in JSON, the format almost every app and web service uses, and turn it into Dart maps and lists with dart:convert.


Video lecture

Subscribe
Placeholder video — the real recording isn't linked yet.