1 | # node-stream-zip [![Build status](https://travis-ci.org/antelle/node-stream-zip.svg?branch=master)](https://travis-ci.org/antelle/node-stream-zip)
|
2 |
|
3 | node.js library for reading and extraction of ZIP archives.
|
4 | Features:
|
5 |
|
6 | - it never loads entire archive into memory, everything is read by chunks
|
7 | - large archives support
|
8 | - all operations are non-blocking, no sync i/o
|
9 | - fast initialization
|
10 | - no dependencies, no binary addons
|
11 | - decompression with built-in zlib module
|
12 | - deflate, deflate64, sfx, macosx/windows built-in archives
|
13 | - ZIP64 support
|
14 |
|
15 | # Installation
|
16 |
|
17 | `$ npm install node-stream-zip`
|
18 |
|
19 | # Usage
|
20 |
|
21 | Open a zip file
|
22 | ```javascript
|
23 | const StreamZip = require('node-stream-zip');
|
24 | const zip = new StreamZip({
|
25 | file: 'archive.zip',
|
26 | storeEntries: true
|
27 | });
|
28 |
|
29 | // Handle errors
|
30 | zip.on('error', err => { /*...*/ });
|
31 | ```
|
32 |
|
33 | List entries
|
34 | ```javascript
|
35 | zip.on('ready', () => {
|
36 | console.log('Entries read: ' + zip.entriesCount);
|
37 | for (const entry of Object.values(zip.entries())) {
|
38 | const desc = entry.isDirectory ? 'directory' : `${entry.size} bytes`;
|
39 | console.log(`Entry ${entry.name}: ${desc}`);
|
40 | }
|
41 | // Do not forget to close the file once you're done
|
42 | zip.close()
|
43 | });
|
44 | ```
|
45 |
|
46 | Stream one entry to stdout
|
47 | ```javascript
|
48 | zip.on('ready', () => {
|
49 | zip.stream('path/inside/zip.txt', (err, stm) => {
|
50 | stm.pipe(process.stdout);
|
51 | stm.on('end', () => zip.close());
|
52 | });
|
53 | });
|
54 | ```
|
55 |
|
56 | Extract one file to disk
|
57 | ```javascript
|
58 | zip.on('ready', () => {
|
59 | zip.extract('path/inside/zip.txt', './extracted.txt', err => {
|
60 | console.log(err ? 'Extract error' : 'Extracted');
|
61 | zip.close();
|
62 | });
|
63 | });
|
64 | ```
|
65 |
|
66 | Extract a folder from archive to disk
|
67 | ```javascript
|
68 | zip.on('ready', () => {
|
69 | fs.mkdirSync('extracted');
|
70 | zip.extract('path/inside/zip/', './extracted', err => {
|
71 | console.log(err ? 'Extract error' : 'Extracted');
|
72 | zip.close();
|
73 | });
|
74 | });
|
75 | ```
|
76 |
|
77 | Extract everything
|
78 | ```javascript
|
79 | zip.on('ready', () => {
|
80 | fs.mkdirSync('extracted');
|
81 | zip.extract(null, './extracted', (err, count) => {
|
82 | console.log(err ? 'Extract error' : `Extracted ${count} entries`);
|
83 | zip.close();
|
84 | });
|
85 | });
|
86 | ```
|
87 |
|
88 | Read a file as buffer in sync way
|
89 | ```javascript
|
90 | zip.on('ready', () => {
|
91 | const data = zip.entryDataSync('path/inside/zip.txt');
|
92 | zip.close();
|
93 | });
|
94 | ```
|
95 |
|
96 | When extracting a folder, you can listen to `extract` event
|
97 | ```javascript
|
98 | zip.on('extract', (entry, file) => {
|
99 | console.log(`Extracted ${entry.name} to ${file}`);
|
100 | });
|
101 | ```
|
102 |
|
103 | `entry` event is generated for every entry during loading
|
104 | ```javascript
|
105 | zip.on('entry', entry => {
|
106 | // you can already stream this entry,
|
107 | // without waiting until all entry descriptions are read (suitable for very large archives)
|
108 | console.log(`Read entry ${entry.name}`);
|
109 | });
|
110 | ```
|
111 |
|
112 | # Options
|
113 |
|
114 | You can pass these options to the constructor
|
115 | - `storeEntries: true` - you will be able to work with entries inside zip archive, otherwise the only way to access them is `entry` event
|
116 | - `skipEntryNameValidation: true` - by default, entry name is checked for malicious characters, like `../` or `c:\123`, pass this flag to disable validation errors
|
117 |
|
118 | # Methods
|
119 |
|
120 | - `zip.entries()` - get all entries description
|
121 | - `zip.entry(name)` - get entry description by name
|
122 | - `zip.stream(entry, function(err, stm) { })` - get entry data reader stream
|
123 | - `zip.entryDataSync(entry)` - get entry data in sync way
|
124 | - `zip.close()` - cleanup after all entries have been read, streamed, extracted, and you don't need the archive
|
125 |
|
126 | # Building
|
127 |
|
128 | The project doesn't require building. To run unit tests with [nodeunit](https://github.com/caolan/nodeunit):
|
129 | `$ npm test`
|
130 |
|
131 | # Known issues
|
132 |
|
133 | - [utf8](https://github.com/rubyzip/rubyzip/wiki/Files-with-non-ascii-filenames) file names
|
134 | - AES encrypted files
|
135 |
|
136 | # Contributors
|
137 |
|
138 | ZIP parsing code has been partially forked from [cthackers/adm-zip](https://github.com/cthackers/adm-zip) (MIT license).
|