从 Deno 中的 Fetch Reader 解压

Untar from a Fetch Reader in Deno

我想弄清楚为什么我使用此代码时不断收到以下错误

[uncaught application error]: Error - checksum error
import { Untar } from "https://deno.land/std@0.128.0/archive/tar.ts";
import { readerFromStreamReader } from "https://deno.land/std@0.128.0/streams/conversion.ts";

const res = await fetch("https://registry.npmjs.org/react/-/react-17.0.2.tgz", { keepalive: true });

if (res.status === 200) {
  const streamReader = res.body!.getReader();
  const reader = readerFromStreamReader(streamReader);
  const untar = new Untar(reader);

  for await (const block of untar) {
   // errors with [uncaught application error]: Error - checksum error
  }
}

你能从这样的流中解压吗?

您流式传输的响应使用 gzip 压缩进行压缩,因此您需要先通过 decompression transform stream 传输流数据:

./so-71365204.ts

import {
  assertExists,
  assertStrictEquals,
} from "https://deno.land/std@0.128.0/testing/asserts.ts";
import { readerFromStreamReader } from "https://deno.land/std@0.128.0/streams/conversion.ts";
import { Untar } from "https://deno.land/std@0.128.0/archive/tar.ts";

const res = await fetch("https://registry.npmjs.org/react/-/react-17.0.2.tgz");

assertStrictEquals(res.status, 200);
assertExists(res.body);

const streamReader = res.body
  .pipeThrough(new DecompressionStream("gzip"))
  .getReader();

const denoReader = readerFromStreamReader(streamReader);
const untar = new Untar(denoReader);

for await (const entry of untar) {
  const { fileName, type } = entry;
  console.log(type, fileName);
}

$ deno run --allow-net=registry.npmjs.org ./so-71365204.ts
file package/LICENSE
file package/index.js
file package/jsx-dev-runtime.js
# etc...