Dart write file
last modified May 30, 2026
In this article we show how to write to files in Dart language.
The dart:io package is used to do IO operations, including writing
files. The File class contains methods for manipulating files and
their contents.
Dart provides both synchronous and asynchronous methods for writing to files,
such as writeAsStringSync and writeAsString.
The openWrite method creates a new IOSink for the
file. It must be explicitly closed when no longer used, to flush buffered data
and free system resources.
The FileMode enum controls how a file is opened for writing. The
default FileMode.write truncates the file before writing, while
FileMode.append adds data at the end of an existing file without
erasing its contents. Other options include FileMode.writeOnly,
which opens the file for writing only.
IOSink API.
Dart writeAsStringSync
The writeAsStringSync method synchronously writes a string to a
file. It opens the file, writes the string in the given encoding (UTF-8 by
default), and closes the file. Because this call blocks the current isolate, it
is best suited for short scripts or situations where the data is small.
import 'dart:io';
void main() {
final fname = 'output.txt';
final f = File(fname);
final data = 'an old falcon\n';
f.writeAsStringSync(data);
print('Data written to $fname');
}
In the program, we write a string into a file synchronously. The file is created if it does not exist. If it exists, it is overwritten.
import 'dart:io';
We import the dart:io library, which provides file system access.
final f = File(fname);
We create a File instance that points to the target path. No I/O
is performed at this point.
final data = 'an old falcon\n'; f.writeAsStringSync(data);
We write the string into the file. The default mode is
FileMode.write, which creates the file if it does not exist or
truncates it if it does.
$ dart main.dart Data written to output.txt $ cat output.txt an old falcon
Dart writeAsString
The writeAsString method opens the file, writes the string in the
given encoding, and closes the file. It returns a
Future<File> that completes with the file object once the
entire operation has finished. This is the preferred approach in asynchronous
code because it does not block the event loop.
import 'dart:io';
void main() async {
final fname = 'output2.txt';
final f = File(fname);
final data = 'a stormy night\n';
await f.writeAsString(data);
print('Data written to $fname');
}
We write a string to a file with the writeAsString method.
void main() async {
Since we use the asynchronous writeAsString method, we add the
async keyword to the main declaration.
await f.writeAsString(data);
The await keyword suspends execution until the
Future returned by writeAsString completes. The
calling isolate remains free to handle other events while the write is in
progress.
Dart writeAsBytesSync
The writeAsBytesSync method synchronously writes a list of bytes
to a file. This is useful when you have binary data or when you need to control
the encoding explicitly.
import 'dart:io';
import 'dart:convert';
void main() {
final fname = 'bytes.txt';
final text = "one 🐘 and three 🐋";
final data = utf8.encode(text);
final f = File(fname);
f.writeAsBytesSync(data);
}
In the example, we write a text message containing emojis to a file using
writeAsBytesSync. Because emojis require more than one byte in
UTF-8, we encode the string explicitly before writing.
import 'dart:convert';
The dart:convert library provides the utf8 codec.
final data = utf8.encode(text);
utf8.encode converts the string into a Uint8List
(a list of bytes). Each emoji encodes to four bytes in UTF-8.
f.writeAsBytesSync(data);
The byte list is written to the file synchronously.
$ dart main.dart $ cat bytes.txt one 🐘 and three 🐋
Dart fetch image
In the next example, we download a binary file from the network and save it to
disk using writeAsBytes.
import 'dart:io';
import 'package:http/http.dart' as http;
void main() async {
final res = await http.get(Uri.http('webcode.me', '/favicon.ico'));
final bdata = res.bodyBytes;
final fname = 'favicon.ico';
final f = File(fname);
await f.writeAsBytes(bdata);
print('Saved $fname (${bdata.length} bytes)');
}
The example downloads a small favicon image and saves the raw bytes to a local file.
import 'package:http/http.dart' as http;
We import the http package to perform the HTTP GET request.
final res = await http.get(Uri.http('webcode.me', '/favicon.ico'));
final bdata = res.bodyBytes;
After awaiting the HTTP response, bodyBytes provides the raw
response body as a Uint8List.
final f = File(fname); await f.writeAsBytes(bdata);
We create a File object and write the byte data asynchronously.
The file is created if it does not exist.
Dart append to file
To append data to an existing file without overwriting its contents, pass
mode: FileMode.append to the write method. If the file does not
exist, it is created automatically.
import 'dart:io';
void main() async {
final fname = 'words.txt';
final words = ['cloud', 'blue', 'book', 'solid'];
final f = File(fname);
for (final word in words) {
await f.writeAsString('$word\n', mode: FileMode.append);
}
print(await f.readAsString());
}
Each iteration appends one word followed by a newline to the file.
await f.writeAsString('$word\n', mode: FileMode.append);
Passing mode: FileMode.append opens the file in append mode for
each write. Without this parameter, each call would use the default
FileMode.write, which truncates the file before writing and would
leave only the last word.
$ dart main.dart cloud blue book solid
Dart IOSink write
The IOSink provides a streaming interface for writing data
incrementally. The write method converts the argument to a string
and appends it to the stream. Multiple write calls accumulate in a
buffer and are flushed when the sink is closed.
import 'dart:io';
void main() async {
final fname = 'test.txt';
final f = File(fname);
final sink = f.openWrite();
sink.write('datetime: ${DateTime.now()}\n');
sink.write('hostname: ${Platform.localHostname}\n');
await sink.close();
}
The example writes two lines — the current date/time and the local hostname —
to the file via an IOSink.
final sink = f.openWrite();
openWrite returns an IOSink backed by the file. By
default it uses FileMode.write, which truncates the file.
sink.write('datetime: ${DateTime.now()}\n');
sink.write('hostname: ${Platform.localHostname}\n');
Each write call adds data to the sink's buffer. String
interpolation with ${...} is used to embed runtime values.
await sink.close();
Awaiting sink.close() ensures all buffered data is flushed to
disk before the program exits.
Dart IOSink writeln
The writeln method writes an object followed by a newline
character. It is a convenient shorthand for write('$object\n').
import 'dart:io';
void main() async {
final fname = 'log.txt';
final f = File(fname);
final sink = f.openWrite();
sink.writeln('INFO app started');
sink.writeln('DEBUG loading config');
sink.writeln('INFO ready');
await sink.close();
print('Log written to $fname');
}
Each writeln call appends the string and a newline to the sink,
producing a simple log file.
$ dart main.dart Log written to log.txt $ cat log.txt INFO app started DEBUG loading config INFO ready
Dart IOSink writeAll
The writeAll method iterates over a collection and writes each
element to the sink. An optional separator string is inserted between
consecutive elements.
import 'dart:io';
void main() async {
final fname = 'words2.txt';
final words = ['sky', 'ocean', 'pen', 'rock', 'storm', 'falcon'];
final f = File(fname);
final sink = f.openWrite();
sink.writeAll(words, '\n');
sink.writeln();
await sink.close();
}
In the example, we write the contents of a list to a file with each word on its own line.
sink.writeAll(words, '\n'); sink.writeln();
The second argument '\n' is the separator placed between elements.
Because no separator is added after the last element, a trailing
writeln() call appends the final newline.
$ dart main.dart $ cat words2.txt sky ocean pen rock storm falcon
Dart write file error handling
File I/O can fail for many reasons: the path may not exist, the process may
lack permission, or the disk may be full. Use a try/catch block
to handle FileSystemException gracefully.
import 'dart:io';
void main() {
final fname = '/root/protected.txt';
final f = File(fname);
try {
f.writeAsStringSync('Hello, World!\n');
print('File written successfully');
} on FileSystemException catch (e) {
print('Failed to write file: ${e.message}');
print('Path: ${e.path}');
}
}
The FileSystemException carries both an error message and the
affected path, making it easy to produce a meaningful diagnostic.
} on FileSystemException catch (e) {
print('Failed to write file: ${e.message}');
print('Path: ${e.path}');
}
We catch the specific FileSystemException rather than the generic
Exception class, which lets us access the
message and path properties.
$ dart main.dart Failed to write file: Permission denied Path: /root/protected.txt
Source
In this article we have shown how to write to files in Dart.
Author
List all Dart tutorials.