Read and write whole directories with tar archive (Standard Library)

我与影子孤独终老i 提交于 2020-06-29 04:07:20

问题


This is a continuation of linked question.

It seems to me, that current implementation of the std/archive/tar.ts module only allows reads and writes per file and not for whole directories.

So far, my reference source are the test files, which only show case single file processing. But what if, for example, a directory ./my-dir/ with multiple files and a tar archive ./test.tar is given.

How can I then utilize append, extract & Co. to efficiently write ./my-dir/ to ./test.tar archive and read all file contents back from it?


回答1:


You can archive a directory by using std/fs/walk

import { walk, walkSync } from "https://deno.land/std/fs/walk.ts";
import { Tar } from "https://deno.land/std/archive/tar.ts";

// Async
const tar = new Tar();

for await (const entry of walk("./dir-to-archive")) {
    if (!entry.isFile) {
        continue;
    }
    await tar.append(entry.path, {
        filePath: entry.path,
    });
}

const writer = await Deno.open("./out.tar", { write: true, create: true });
await Deno.copy(tar.getReader(), writer);

Untar implementation for folders/multiple files was broken, it was fixed by this PR and currently available in master using https://deno.land/std/archive/tar.ts

import { Untar } from "https://deno.land/std/archive/tar.ts";
import { ensureFile } from "https://deno.land/std/fs/ensure_file.ts";
import { ensureDir } from "https://deno.land/std/fs/ensure_dir.ts";

const reader = await Deno.open("./out.tar", { read: true });
const untar = new Untar(reader);

for await (const entry of untar) {
  console.log(entry); // metadata
  /*
    fileName: "archive/deno.txt",
    fileMode: 33204,
    mtime: 1591657305,
    uid: 0,
    gid: 0,
    size: 24400,
    type: 'file'
  */

  if (entry.type === "directory") {
    await ensureDir(entry.fileName);
    continue;
  }

  await ensureFile(entry.fileName);
  const file = await Deno.open(entry.fileName, { write: true });
  // <entry> is a reader
  await Deno.copy(entry, file);
}
reader.close();

Update

Created a lib to allow transformations, including gzip/gunzip to create & read .tar.gz

gzip

import * as Transform from "https://deno.land/x/transform/mod.ts";
const { GzEncoder } = Transform.Transformers;

/** ... **/
const writer = await Deno.open("./out.tar.gz", { write: true, create: true });
await Transform.pipeline(tar.getReader(), new GzEncoder())
    .to(writer);

writer.close();

gunzip

import * as Transform from "https://deno.land/x/transform/mod.ts";
const { GzDecoder } = Transform.Transformers;

/** ... **/
const reader = await Deno.open("./out.tar.gz", { read: true });
const untar = new Untar(
    Transform.newReader(input, new GzDecoder())
);

for await (const entry of untar) {
    console.log(entry);
}



来源:https://stackoverflow.com/questions/62270112/read-and-write-whole-directories-with-tar-archive-standard-library

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!