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();