#How to extract Zstandard-compressed tar files using Zig stdlib (0.15.2)

1 messages · Page 1 of 1 (latest)

atomic rain
#

Hello.
I’m currently developing software with Zig 0.15.2 that needs to extract a tar file compressed with zstandard and then obtain a list of the extracted files or directories.
How can I accomplish this using Zig’s standard library?
I’ve found that std.tar and std.compress.zstd.Decompress exist and looked through the standard library, but I have no idea how to use them.
This is also my first time asking a question here, so I’m not even sure if I’m formatting this correctly. Thank you in advance.

sullen ether
# atomic rain Hello. I’m currently developing software with Zig 0.15.2 that needs to extract a...

Following the docs:
https://ziglang.org/documentation/master/std/#std.compress.zstd.Decompress
https://ziglang.org/documentation/master/std/#std.tar.Iterator
I assume something like this:

const compressed_reader: *std.Io.Reader = ...

var zstd_stream = std.compress.zstd.Decompress.init(compressed_reader, &.{}, .{}); // optional buffering
const uncompressed_reader = &zstd_stream.reader;

var tar_stream = std.tar.Iterator.init(uncompressed_reader, .{});
while (try tar_stream.next()) |entry| {
  switch (entry.kind) {
    .directory => {}, // handle as you wish
    .sym_link => {}, // handle as you wish
    .file => { // example handling
      var file = try std.fs.cwd().openFile(entry.name, .{});
      defer file.close();

      var file_writer = file.writer(&.{}); // optional buffering
      try tar_stream.streamRemaining(entry, &file_writer.interface);
      try file_writer.flush();
    },
  }
}
atomic rain
granite monolith
#

for this particular example you'd probably need a buffer of size std.compress.zstd.default_window_len + std.compress.zstd.block_size_max for zstd.Decompress

atomic rain
#

By the way, sorry if this is a beginner question, but how can I get a std.io.Reader from a std.fs.File?
Should I use std.fs.File.Reader.interface for that?

velvet shore
#

file.reader(&buffer) or file.readerStreaming(&buffer, former for most files, latter if you know the file doesnt support pread eg stdin.
the former will automatically convert to the latter but it wastes a syscall.

#

do not copy interface out of the file reader