Dart WritePipe
last modified October 18, 2026
The WritePipe interface in Dart represents the writable end of an
anonymous operating system pipe. It is part of the dart:io
library and shares the familiar IOSink API used by files and
sockets.
A WritePipe is not created directly. You obtain one from
Pipe.create().write or by extracting it from a
ResourceHandle with toWritePipe.
Basic Definition
WritePipe is an abstract interface class that implements
IOSink. It provides write, writeln,
add, addStream, flush, and
close.
Text written to a WritePipe is encoded using the sink's encoding,
which defaults to UTF-8. Byte lists are written unchanged.
Basic WritePipe Usage
This example writes text to a pipe and reads it back from the other end.
import 'dart:convert';
import 'dart:io';
Future<void> main() async {
var pipe = await Pipe.create();
var result = pipe.read.transform(utf8.decoder).join();
var writePipe = pipe.write;
writePipe.write('Hello, World!');
await writePipe.close();
print(await result);
}
We obtain the write end from pipe.write, write a string, and close
it so the reader sees end-of-file. The result confirms that the bytes arrived
intact.
$ dart main.dart Hello, World!
Writing Multiple Chunks
This example demonstrates writing data in multiple chunks using a
WritePipe.
import 'dart:convert';
import 'dart:io';
Future<void> main() async {
var pipe = await Pipe.create();
var result = pipe.read.transform(utf8.decoder).join();
var writePipe = pipe.write;
for (var i = 0; i < 5; i++) {
writePipe.writeln('Chunk $i');
print('Wrote chunk $i');
}
await writePipe.close();
print('All chunks written');
print(await result);
}
Each writeln appends the text and a newline. Closing the write end
flushes the buffered data. The reader then receives all five lines as one
stream.
$ dart main.dart Wrote chunk 0 Wrote chunk 1 Wrote chunk 2 Wrote chunk 3 Wrote chunk 4 All chunks written Chunk 0 Chunk 1 Chunk 2 Chunk 3 Chunk 4
Error Handling
This example shows the error produced when writing to a closed pipe.
import 'dart:io';
Future<void> main() async {
var pipe = await Pipe.create();
var writePipe = pipe.write;
await writePipe.close();
try {
writePipe.write('Test data');
await writePipe.flush();
} catch (e) {
print('Error occurred: $e');
}
}
Once a WritePipe is closed, further writes throw a
StateError. Catch and handle this error if the writer's lifetime
is not fully controlled.
$ dart main.dart Error occurred: Bad state: StreamSink is closed
Writing Binary Data
This example demonstrates writing binary data through a WritePipe.
import 'dart:io';
import 'dart:typed_data';
Future<void> main() async {
var pipe = await Pipe.create();
var result = pipe.read.expand((chunk) => chunk).toList();
var writePipe = pipe.write;
var data = Uint8List.fromList([0, 1, 2, 3, 4, 5]);
writePipe.add(data);
await writePipe.close();
print('Binary data written: ${await result}');
}
add writes a byte list without text encoding. Reading the other
end with expand produces the original byte sequence.
$ dart main.dart Binary data written: [0, 1, 2, 3, 4, 5]
Writing to a Socket
A network socket is also an IOSink, so it uses the same writing
methods as a WritePipe. This example sends an HTTP request to a
local server and reads it back.
import 'dart:io';
Future<void> main() async {
var server = await ServerSocket.bind(InternetAddress.loopbackIPv4, 0);
var received = server.first.then((socket) async {
var bytes = await socket.expand((chunk) => chunk).toList();
await socket.close();
return String.fromCharCodes(bytes);
});
var client = await Socket.connect(InternetAddress.loopbackIPv4, server.port);
client.write('GET / HTTP/1.1\r\n');
client.write('Host: localhost\r\n');
client.write('Connection: close\r\n\r\n');
await client.close();
client.destroy();
print('Received by server:');
print((await received).trim());
await server.close();
}
The socket's write and close methods come from
IOSink. After closing the sending side, destroy
releases the client socket completely. The server drains its accepted socket,
closes it, and returns the received request text.
$ dart main.dart Received by server: GET / HTTP/1.1 Host: localhost Connection: close
Best Practices
- Always close: Close the write end when no more data will be written
- Await flush or close: Ensure buffered data is delivered before reading or exiting
- Handle errors: Catch
StateErrorwhen writing to a possibly closed sink - Use bytes for binary data: Write
List<int>withaddinstead of text methods - Consume the read end: Keep reading from the other end to avoid blocking the writer
Source
This tutorial covered Dart's WritePipe interface with practical
examples showing text writing, multiple chunks, errors, binary data, and
socket output.
Author
List all Dart tutorials.