All Projects → simolus3 → tar

simolus3 / tar

Licence: MIT License
Memory-efficient, streaming implementation of the tar archive format in Dart

Programming Languages

dart
5743 projects
shell
77523 projects

Projects that are alternatives of or similar to tar

Libarchivejs
Archive library for browsers
Stars: ✭ 145 (+705.56%)
Mutual labels:  tar, archive
Casync
Content-Addressable Data Synchronization Tool
Stars: ✭ 890 (+4844.44%)
Mutual labels:  tar, archive
Discord-Reposter
Bot for reposting Discord messages (work in progress)
Stars: ✭ 62 (+244.44%)
Mutual labels:  archive
sio-go
Authenticated encryption for streams in Go
Stars: ✭ 21 (+16.67%)
Mutual labels:  io
SingleFile-Lite
Feel the power of the Manifest V3. The future, right now!
Stars: ✭ 55 (+205.56%)
Mutual labels:  archive
reactor
Asynchronous Event Driven IO for .NET
Stars: ✭ 40 (+122.22%)
Mutual labels:  io
terraform-provider-archive
Terraform archive provider
Stars: ✭ 54 (+200%)
Mutual labels:  archive
history-project
📜 Historical record of happenings at the Nottingham New Theatre.
Stars: ✭ 15 (-16.67%)
Mutual labels:  archive
PyTOUGH
A Python library for automating TOUGH2 simulations of subsurface fluid and heat flow
Stars: ✭ 64 (+255.56%)
Mutual labels:  io
toyhttpd
I/O 模型练手代码,分别使用阻塞式 I/O、select、poll 和 epoll 和 Java NIO 实现了简单的 HTTP Server
Stars: ✭ 43 (+138.89%)
Mutual labels:  io
Ogar3
A better version of Ogar
Stars: ✭ 22 (+22.22%)
Mutual labels:  io
archivebot
💾 A telegram bot for backing up and collecting all kinds of media.
Stars: ✭ 65 (+261.11%)
Mutual labels:  archive
BBIOConfig
A GUI for the BB universal IO
Stars: ✭ 39 (+116.67%)
Mutual labels:  io
Diskernet
💾 Diskernet - An internet on yer disk. Full text search archive from your browsing and bookmarks. Weclome! to the Diskernet: Your preferred backup solution. It's like you're still online! Disconnect with Diskernet, an internet for the post-online apocalypse. Or the airplane WiFi. Or the site goes down. Or ... You get the picture. Get Diskernet.…
Stars: ✭ 2,788 (+15388.89%)
Mutual labels:  archive
herodotus-core
Content Archiving Software 📜
Stars: ✭ 34 (+88.89%)
Mutual labels:  archive
PLzmaSDK
PLzmaSDK is (Portable, Patched, Package, cross-P-latform) Lzma SDK.
Stars: ✭ 28 (+55.56%)
Mutual labels:  tar
ratarmount
Random Access Read-Only Tar Mount
Stars: ✭ 217 (+1105.56%)
Mutual labels:  tar
io-handbook
Handbook of IO
Stars: ✭ 13 (-27.78%)
Mutual labels:  io
eliminate
Delete files and directories without all the bullshit.
Stars: ✭ 51 (+183.33%)
Mutual labels:  io
go-mtree
File systems verification utility and library, in likeness of mtree(8)
Stars: ✭ 55 (+205.56%)
Mutual labels:  tar

tar

Build status

This package provides stream-based readers and writers for tar files.

When working with large tar files, this library consumes considerably less memory than package:archive, although it is slightly slower due to the async overhead.

Reading

To read entries from a tar file, use a TarReader with a Stream emitting bytes (as List<int>):

import 'dart:convert';
import 'dart:io';
import 'package:tar/tar.dart';

Future<void> main() async {
  final reader = TarReader(File('file.tar').openRead());

  while (await reader.moveNext()) {
    final entry = reader.current;
    // Use reader.header to see the header of the current tar entry
    print(entry.header.name);
    // And reader.contents to read the content of the current entry as a stream
    print(await entry.contents.transform(utf8.decoder).first);
  }
  // Note that the reader will automatically close if moveNext() returns false or
  // throws. If you want to close a tar stream before that happens, use
  // reader.cancel();
}

To read .tar.gz files, transform the stream with gzip.decoder before passing it to the TarReader.

To easily go through all entries in a tar file, use TarReader.forEach:

Future<void> main() async {
  final inputStream = File('file.tar').openRead();

  await TarReader.forEach(inputStream, (entry) {
    print(header.name);
    print(await entry.contents.transform(utf8.decoder).first);
  });
}

Warning: Since the reader is backed by a single stream, concurrent calls to read are not allowed! Similarly, if you're reading from an entry's contents, make sure to fully drain the stream before calling read() again.

Writing

When writing archives, package:tar expects a Stream of tar entries to include in the archive. This stream can then be converted into a stream of byte-array chunks forming the encoded tar archive.

To write a tar stream into a StreamSink<List<int>>, such as an IOSink returned by File.openWrite, use tarWritingSink:

import 'dart:convert';
import 'dart:io';
import 'package:tar/tar.dart';

Future<void> main() async {
  final output = File('test.tar').openWrite();
  final tarEntries = Stream<TarEntry>.value(
    TarEntry.data(
      TarHeader(
        name: 'hello.txt',
        mode: int.parse('644', radix: 8),
      ),
      utf8.encode('Hello world'),
    ),
  );

  await tarEntries.pipe(tarWritingSink(output));
}

For more complex stream transformations, tarWriter can be used as a stream transformer converting a stream of tar entries into archive bytes.

Together with the gzip.encoder transformer from dart:io, this can be used to write a .tar.gz file:

import 'dart:io';
import 'package:tar/tar.dart';

Future<void> write(Stream<TarEntry> entries) {
  return entries
      .transform(tarWriter) // convert entries into a .tar stream
      .transform(gzip.encoder) // convert the .tar stream into a .tar.gz stream
      .pipe(File('output.tar.gz').openWrite());
}

A more complex example for writing files can be found in example/archive_self.dart.

Encoding options

By default, tar files are written in the pax format defined by the POSIX.1-2001 specification (--format=posix in GNU tar). When all entries have file names shorter than 100 chars and a size smaller than 8 GB, this is equivalent to the ustar format. This library won't write PAX headers when there is no reason to do so. If you prefer writing GNU-style long filenames instead, you can use the format option:

Future<void> write(Stream<TarEntry> entries) {
  return entries
      .pipe(
        tarWritingSink(
          File('output.tar').openWrite(),
          format: OutputFormat.gnuLongName,
      ));
}

To change the output format on the tarWriter transformer, use tarWriterWith.

Synchronous writing

As the content of tar entries is defined as an asynchronous stream, the tar encoder is asynchronous too. The more specific SynchronousTarEntry class stores tar content as a list of bytes, meaning that it can be written synchronously.

To synchronously write tar files, use tarConverter (or tarConverterWith for options):

List<int> createTarArchive(Iterable<SynchronousTarEntry> entries) {
  late List<int> result;
  final sink = ByteConversionSink.withCallback((data) => result = data);

  final output = tarConverter.startChunkedConversion(sink);
  entries.forEach(output.add);
  output.close();

  return result;
}

Features

  • Supports v7, ustar, pax, gnu and star archives
  • Supports extended pax headers for long file or link names
  • Supports long file and link names generated by GNU-tar
  • Hardened against denial-of-service attacks with invalid tar files

Big thanks to Garett Tok Ern Liang for writing the initial Dart tar reader that this library is based on.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].