tarCodec top-level constant
TarCodec
const tarCodec
Not a standard dart:convert Codec because it doesn't perform simple
byte-to-byte conversions, acting purely as a StreamTransformer.
Please note that onDone may never be called on failure, you have to listen for both onError and onDone to identify the end of stream. Example for .decoder:
import 'package:archive/archive.dart';
import 'dart:io';
import 'package:path/path.dart' as p;
final request = await HttpClient()
.getUrl(Uri.parse('https://example.com/data.tar.zst'));
final HttpClientResponse response = await request.close();
await for (final TarEntry entry in response
// also available for xz/zstd/bzip2/tar
.transform(zstdCodec.decoder)
.transform(tarCodec.decoder)) {
final target = p.join('out', entry.name);
if (!p.isWithin('out', target)) continue; // `../` would escape out/
if (entry.type == TarEntryType.file) {
await File(target).create(recursive: true);
await entry.content.pipe(File(target).openWrite());
}
}
Example for .encoder:
Stream<ArchiveFile> filesOf(Directory dir) async* {
await for (final entity in dir.list(recursive: true)) {
if (entity is File) {
final input = InputFileStream(entity.path);
try {
yield ArchiveFile.stream(
p.relative(entity.path, from: dir.path), input);
} finally {
// Runs once the encoder has written the entry, or when it is
// cancelled
await input.close();
}
}
}
}
final upload =
await HttpClient().putUrl(Uri.parse('https://example.com/backup'));
upload.headers.contentType = ContentType('application', 'zstd');
await upload.addStream(filesOf(Directory('data'))
// also available for zip/tar
.transform(zipCodec.encoder) // Stream<ArchiveFile> -> Stream<List<int>>
// also available for zstd/xz/bzip2
.transform(zstdCodec.encoder));
final response = await upload.close();
Implementation
const tarCodec = TarCodec();