Working with Files
Prerequisites: Futures and async/await
The dart:io library reads and writes files in command-line programs
and servers. (Flutter apps use the same API, together with the
path_provider package to find the right folder on each device.
dart:io isn't available on the web.)
Reading and writing text
import 'dart:io';
Future<void> main() async {
final file = File('${Directory.systemTemp.path}/notes.txt');
await file.writeAsString('First line\nSecond line\n');
await file.writeAsString('Third line\n', mode: FileMode.append);
final text = await file.readAsString();
print(text.trim());
final lines = await file.readAsLines();
print(lines.length);
print(await file.exists());
await file.delete();
print(await file.exists());
}
First line
Second line
Third line
3
true
false
- File operations return futures, so
awaitthem. (Synchronous versions such asreadAsStringSyncexist for simple scripts.) FileMode.appendadds to the end instead of replacing.
Large files: streaming lines
readAsString loads the whole file into memory. For big files, read it as
a stream of lines:
import 'dart:convert';
import 'dart:io';
Future<void> main() async {
final log = File('${Directory.systemTemp.path}/app.log');
await log.writeAsString('INFO start\nERROR disk full\nINFO retry\nERROR timeout\n');
final errors = <String>[];
await for (final line in log.openRead().transform(utf8.decoder).transform(const LineSplitter())) {
if (line.startsWith('ERROR')) errors.add(line.substring(6));
}
print(errors);
await log.delete();
}
[disk full, timeout]
await for processes each line as it arrives — streams are covered in
depth in Level 3.
Folders
import 'dart:io';
Future<void> main() async {
final dir = Directory('${Directory.systemTemp.path}/dart_demo');
await dir.create(recursive: true);
await File('${dir.path}/a.txt').writeAsString('a');
await File('${dir.path}/b.md').writeAsString('b');
final names = await dir.list().map((e) => e.uri.pathSegments.last).toList();
print(names..sort());
await dir.delete(recursive: true);
}
[a.txt, b.md]
The path package (package:path) builds and splits paths correctly on
every operating system.
Common mistakes
- Reading a missing file throws a
PathNotFoundException(aFileSystemException). Checkexists()or catch it. - Relative paths are relative to where the program was started, not to the source file.