FileByteSink class final

A staged file sink that commits its staging file on close.

With overwriting enabled, the staging file is atomically renamed over the destination after its per-staging ownership marker, metadata, and contents have been verified. Cleanup uses the same evidence and fails closed: if the staging pathname cannot be shown to still name the owned file, it is left in place and cleanup failure is reported rather than risking deletion of a replacement.

With overwriting disabled, this API does not promise strict atomic no-clobber semantics. Portable Dart APIs provide neither an atomic no-replace rename nor an exclusive create that returns an open handle. Instead, close exclusively creates the destination, reopens it without truncation, and establishes probabilistic ownership with a cryptographically random marker before writing through the retained handle.

A path replacement detected at any checkpoint fails closed and is neither modified nor deleted. Failed commits deliberately leave the reservation behind because portable Dart cannot safely unlink a path after checking it without another replacement race. The destination can also be briefly visible as an empty, marked, or partially written file.

There are unavoidable portable TOCTOU limitations between metadata/content verification and opening, renaming, or deleting a pathname: dart:io exposes neither stable file identity nor atomic create-and-open/no-replace rename. In particular, a replacement that reproduces the verified metadata and contents, or is installed after verification, cannot be distinguished. Platforms needing strict filesystem-level guarantees must provide native atomic primitives outside this implementation.

Implemented types

Properties

hashCode → int
The hash code for this object.
no setterinherited
length → Future<int>
Number of bytes currently written to the sink.
no setteroverride
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited

Methods

abort() → Future<void>
Discards staged bytes. Calling this more than once is harmless.
append(List<int> bytes) → Future<void>
Appends bytes to the end of the sink.
override
close() → Future<void>
Finishes the sink and releases any associated resources.
override
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toString() → String
A string representation of this object.
inherited
truncate(int length) → Future<void>
Truncates the staged output to length bytes.
writeAt(int offset, List<int> bytes) → Future<void>
Replaces existing bytes beginning at offset without changing the length.
override

Operators

operator ==(Object other) → bool
The equality operator.
inherited

Static Methods

open(String path, {bool overwrite = true, FileByteSinkTestHooks? testHooks}) → Future<FileByteSink>
Opens a staged sink that commits to path when close succeeds.