{"id":13454756,"url":"https://github.com/mafintosh/tar-stream","last_synced_at":"2025-05-14T12:09:37.425Z","repository":{"id":12668145,"uuid":"15340089","full_name":"mafintosh/tar-stream","owner":"mafintosh","description":"tar-stream is a streaming tar parser and generator.","archived":false,"fork":false,"pushed_at":"2024-06-14T07:44:28.000Z","size":232,"stargazers_count":421,"open_issues_count":13,"forks_count":97,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-02T02:09:51.746Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mafintosh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-12-20T14:21:55.000Z","updated_at":"2025-03-21T06:06:39.000Z","dependencies_parsed_at":"2024-01-12T00:27:11.693Z","dependency_job_id":"d8fc769b-a9b9-4566-b3d9-34b791e89ebf","html_url":"https://github.com/mafintosh/tar-stream","commit_stats":{"total_commits":217,"total_committers":43,"mean_commits":5.046511627906977,"dds":0.2764976958525346,"last_synced_commit":"126968fd3c4a39eba5f8318c255e04cedbbad176"},"previous_names":[],"tags_count":65,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mafintosh%2Ftar-stream","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mafintosh%2Ftar-stream/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mafintosh%2Ftar-stream/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mafintosh%2Ftar-stream/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mafintosh","download_url":"https://codeload.github.com/mafintosh/tar-stream/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247941699,"owners_count":21022038,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T08:00:57.673Z","updated_at":"2025-04-09T03:10:48.341Z","avatar_url":"https://github.com/mafintosh.png","language":"JavaScript","readme":"# tar-stream\n\ntar-stream is a streaming tar parser and generator and nothing else. It operates purely using streams which means you can easily extract/parse tarballs without ever hitting the file system.\n\nNote that you still need to gunzip your data if you have a `.tar.gz`. We recommend using [gunzip-maybe](https://github.com/mafintosh/gunzip-maybe) in conjunction with this.\n\n```\nnpm install tar-stream\n```\n\n[![build status](https://secure.travis-ci.org/mafintosh/tar-stream.png)](http://travis-ci.org/mafintosh/tar-stream)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](http://opensource.org/licenses/MIT)\n\n## Usage\n\ntar-stream exposes two streams, [pack](https://github.com/mafintosh/tar-stream#packing) which creates tarballs and [extract](https://github.com/mafintosh/tar-stream#extracting) which extracts tarballs. To [modify an existing tarball](https://github.com/mafintosh/tar-stream#modifying-existing-tarballs) use both.\n\n\nIt implementes USTAR with additional support for pax extended headers. It should be compatible with all popular tar distributions out there (gnutar, bsdtar etc)\n\n## Related\n\nIf you want to pack/unpack directories on the file system check out [tar-fs](https://github.com/mafintosh/tar-fs) which provides file system bindings to this module.\n\n## Packing\n\nTo create a pack stream use `tar.pack()` and call `pack.entry(header, [callback])` to add tar entries.\n\n``` js\nconst tar = require('tar-stream')\nconst pack = tar.pack() // pack is a stream\n\n// add a file called my-test.txt with the content \"Hello World!\"\npack.entry({ name: 'my-test.txt' }, 'Hello World!')\n\n// add a file called my-stream-test.txt from a stream\nconst entry = pack.entry({ name: 'my-stream-test.txt', size: 11 }, function(err) {\n  // the stream was added\n  // no more entries\n  pack.finalize()\n})\n\nentry.write('hello')\nentry.write(' ')\nentry.write('world')\nentry.end()\n\n// pipe the pack stream somewhere\npack.pipe(process.stdout)\n```\n\n## Extracting\n\nTo extract a stream use `tar.extract()` and listen for `extract.on('entry', (header, stream, next) )`\n\n``` js\nconst extract = tar.extract()\n\nextract.on('entry', function (header, stream, next) {\n  // header is the tar header\n  // stream is the content body (might be an empty stream)\n  // call next when you are done with this entry\n\n  stream.on('end', function () {\n    next() // ready for next entry\n  })\n\n  stream.resume() // just auto drain the stream\n})\n\nextract.on('finish', function () {\n  // all entries read\n})\n\npack.pipe(extract)\n```\n\nThe tar archive is streamed sequentially, meaning you **must** drain each entry's stream as you get them or else the main extract stream will receive backpressure and stop reading.\n\n## Extracting as an async iterator\n\nThe extraction stream in addition to being a writable stream is also an async iterator\n\n``` js\nconst extract = tar.extract()\n\nsomeStream.pipe(extract)\n\nfor await (const entry of extract) {\n  entry.header // the tar header\n  entry.resume() // the entry is the stream also\n}\n```\n\n## Headers\n\nThe header object using in `entry` should contain the following properties.\nMost of these values can be found by stat'ing a file.\n\n``` js\n{\n  name: 'path/to/this/entry.txt',\n  size: 1314,        // entry size. defaults to 0\n  mode: 0o644,       // entry mode. defaults to to 0o755 for dirs and 0o644 otherwise\n  mtime: new Date(), // last modified date for entry. defaults to now.\n  type: 'file',      // type of entry. defaults to file. can be:\n                     // file | link | symlink | directory | block-device\n                     // character-device | fifo | contiguous-file\n  linkname: 'path',  // linked file name\n  uid: 0,            // uid of entry owner. defaults to 0\n  gid: 0,            // gid of entry owner. defaults to 0\n  uname: 'maf',      // uname of entry owner. defaults to null\n  gname: 'staff',    // gname of entry owner. defaults to null\n  devmajor: 0,       // device major version. defaults to 0\n  devminor: 0        // device minor version. defaults to 0\n}\n```\n\n## Modifying existing tarballs\n\nUsing tar-stream it is easy to rewrite paths / change modes etc in an existing tarball.\n\n``` js\nconst extract = tar.extract()\nconst pack = tar.pack()\nconst path = require('path')\n\nextract.on('entry', function (header, stream, callback) {\n  // let's prefix all names with 'tmp'\n  header.name = path.join('tmp', header.name)\n  // write the new entry to the pack stream\n  stream.pipe(pack.entry(header, callback))\n})\n\nextract.on('finish', function () {\n  // all entries done - lets finalize it\n  pack.finalize()\n})\n\n// pipe the old tarball to the extractor\noldTarballStream.pipe(extract)\n\n// pipe the new tarball the another stream\npack.pipe(newTarballStream)\n```\n\n## Saving tarball to fs\n\n\n``` js\nconst fs = require('fs')\nconst tar = require('tar-stream')\n\nconst pack = tar.pack() // pack is a stream\nconst path = 'YourTarBall.tar'\nconst yourTarball = fs.createWriteStream(path)\n\n// add a file called YourFile.txt with the content \"Hello World!\"\npack.entry({ name: 'YourFile.txt' }, 'Hello World!', function (err) {\n  if (err) throw err\n  pack.finalize()\n})\n\n// pipe the pack stream to your file\npack.pipe(yourTarball)\n\nyourTarball.on('close', function () {\n  console.log(path + ' has been written')\n  fs.stat(path, function(err, stats) {\n    if (err) throw err\n    console.log(stats)\n    console.log('Got file info successfully!')\n  })\n})\n```\n\n## Performance\n\n[See tar-fs for a performance comparison with node-tar](https://github.com/mafintosh/tar-fs/blob/master/README.md#performance)\n\n# License\n\nMIT\n","funding_links":[],"categories":["Packages","Repository","包","JavaScript","Compression","目录","Modules","Number","compress (压缩)"],"sub_categories":["Compression","Streams","压缩"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmafintosh%2Ftar-stream","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmafintosh%2Ftar-stream","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmafintosh%2Ftar-stream/lists"}