ダウンロードと解凍の簡単な解決策を探している.Zip
または .tar.gz
任意のオペレーティングシステム上のNode.jsのファイル。
これが組み込まれているのか、別のライブラリを使用する必要があるのかはわかりません。何か案は?ほんの2、3行のコードを探しているので、次のZipファイルが来て、ノードにダウンロードしたい場合、それは簡単です。これは簡単で、組み込みである必要がありますが、何も見つかりません。ありがとう!
チェックアウト adm-Zip 。
ADM-Zipは、NodeJSのZipデータ圧縮用の純粋なJavaScript実装です。
ライブラリでは次のことができます。
- zipファイルをディスクまたはメモリ内バッファに直接解凍します
- ファイルを圧縮し、
.Zip
形式または圧縮バッファでディスクに保存します- 既存の
.Zip
のコンテンツの更新/新しいファイルの追加/削除
2017年です(正確には10月26日)。
Unzipなどの古くから普及している技術の場合、「完全」であるため「停滞」および「維持されない」かなり人気のある成熟したnode.js unzipライブラリが存在することを期待します。
しかし、ほとんどのライブラリは完全にひどいものであるか、ほんの数か月前に最近コミットされたようです。これは非常に懸念事項です...なので、いくつかの解凍ライブラリを調べ、ドキュメントを読んで、WTFを理解するために例を試しました。たとえば、私はこれらを試しました:
yauzl
node-stream-Zip
_node-unzipper
_node-unzip
_jszip
Zip
yauzl
完全にダウンロードされたファイルに最適です。ストリーミングにはあまり適していません。
よく文書化されています。うまくいく。理にかなっています。
node-stream-Zip
_antelleの _node-stream-Zip
_ が最高のようです
インストール:
_npm install --save node-stream-Zip
_
使用法:
_'use strict';
var StreamZip = require('node-stream-Zip');
var Zip = new StreamZip({
file: './example.Zip'
, storeEntries: true
});
Zip.on('error', function (err) { console.error('[ERROR]', err); });
Zip.on('ready', function () {
console.log('All entries read: ' + Zip.entriesCount);
//console.log(Zip.entries());
});
Zip.on('entry', function (entry) {
var pathname = path.resolve('./temp', entry.name);
if (/\.\./.test(path.relative('./temp', pathname))) {
console.warn("[Zip warn]: ignoring maliciously crafted paths in Zip file:", entry.name);
return;
}
if ('/' === entry.name[entry.name.length - 1]) {
console.log('[DIR]', entry.name);
return;
}
console.log('[FILE]', entry.name);
Zip.stream(entry.name, function (err, stream) {
if (err) { console.error('Error:', err.toString()); return; }
stream.on('error', function (err) { console.log('[ERROR]', err); return; });
// example: print contents to screen
//stream.pipe(process.stdout);
// example: save contents to file
mkdirp(path.dirname(pathname, function (err) {
stream.pipe(fs.createWriteStream(pathname));
});
});
});
_
セキュリティ警告:
誤って解決される悪意を持って作成されたパス(_entry.name
_や_../../../foo
_など)を_/etc/passwd
_でチェックするかどうかはわかりません。
/\.\./.test(path.relative('./to/dir', path.resolve('./to/dir', entry.name)))
を比較することで、自分で簡単に確認できます。
長所:(なぜ最高だと思いますか?)
短所:
Zip.extract()
は機能しないようです(したがって、この例ではZip.stream()
を使用しました)インストール:
_npm install --save unzipper
_
使用法:
_'use strict';
var fs = require('fs');
var unzipper = require('unzipper');
fs.createReadStream('./example.Zip')
.pipe(unzipper.Parse())
.on('entry', function (entry) {
var fileName = entry.path;
var type = entry.type; // 'Directory' or 'File'
console.log();
if (/\/$/.test(fileName)) {
console.log('[DIR]', fileName, type);
return;
}
console.log('[FILE]', fileName, type);
// TODO: probably also needs the security check
entry.pipe(process.stdout/*fs.createWriteStream('output/path')*/);
// NOTE: To ignore use entry.autodrain() instead of entry.pipe()
});
_
長所:
node-stream-Zip
_と同様の方法で動作するようですが、制御が少ないunzip
のより機能的なフォーク短所:
Nodeにはgzipの組み込みサポートがあり、 zlibモジュール を使用して収縮します:
var zlib = require('zlib');
zlib.gunzip(gzipBuffer, function(err, result) {
if(err) return console.error(err);
console.log(result);
});
編集:pipe
でさえも直接データを介してGunzip
( request を使用):
var request = require('request'),
zlib = require('zlib'),
fs = require('fs'),
out = fs.createWriteStream('out');
// Fetch http://example.com/foo.gz, gunzip it and store the results in 'out'
request('http://example.com/foo.gz').pipe(zlib.createGunzip()).pipe(out);
Tarアーカイブには、Isaacsの tarモジュール があり、npmで使用されます。
編集2:zlib
はZip
形式をサポートしないため、回答を更新しました。これはgzip
でのみ機能します。
yauzl は、解凍用の堅牢なライブラリです。設計原則:
現在、テスト範囲は97%です。
私はadm-Zipやunzipなどのnodejs unzipライブラリをいくつか試した後、yauzlのラッパーであるextract-Zipに決めました。実装が最も簡単なようです。
https://www.npmjs.com/package/extract-Zip
var extract = require('extract-Zip')
extract(zipfile, { dir: outputPath }, function (err) {
// handle err
})
私はこれを長い間楽しみにしていましたが、簡単な作業例は見つかりませんでしたが、これらの回答に基づいてdownloadAndUnzip()
関数を作成しました。
使い方はとても簡単です:
downloadAndUnzip('http://your-domain.com/archive.Zip', 'yourfile.xml')
.then(function (data) {
console.log(data); // unzipped content of yourfile.xml in root of archive.Zip
})
.catch(function (err) {
console.error(err);
});
そして、ここに宣言があります:
var AdmZip = require('adm-Zip');
var request = require('request');
var downloadAndUnzip = function (url, fileName) {
/**
* Download a file
*
* @param url
*/
var download = function (url) {
return new Promise(function (resolve, reject) {
request({
url: url,
method: 'GET',
encoding: null
}, function (err, response, body) {
if (err) {
return reject(err);
}
resolve(body);
});
});
};
/**
* Unzip a Buffer
*
* @param buffer
* @returns {Promise}
*/
var unzip = function (buffer) {
return new Promise(function (resolve, reject) {
var resolved = false;
var Zip = new AdmZip(buffer);
var zipEntries = Zip.getEntries(); // an array of ZipEntry records
zipEntries.forEach(function (zipEntry) {
if (zipEntry.entryName == fileName) {
resolved = true;
resolve(zipEntry.getData().toString('utf8'));
}
});
if (!resolved) {
reject(new Error('No file found in archive: ' + fileName));
}
});
};
return download(url)
.then(unzip);
};
.Zipで動作する次のもので成功しました。
(投稿用にここで簡略化:エラーチェックなし&すべてのファイルを現在のフォルダーに解凍します)
function DownloadAndUnzip(URL){
var unzip = require('unzip');
var http = require('http');
var request = http.get(URL, function(response) {
response.pipe(unzip.Extract({path:'./'}))
});
}
別の実例:
var zlib = require('zlib');
var tar = require('tar');
var ftp = require('ftp');
var files = [];
var conn = new ftp();
conn.on('connect', function(e)
{
conn.auth(function(e)
{
if (e)
{
throw e;
}
conn.get('/tz/tzdata-latest.tar.gz', function(e, stream)
{
stream.on('success', function()
{
conn.end();
console.log("Processing files ...");
for (var name in files)
{
var file = files[name];
console.log("filename: " + name);
console.log(file);
}
console.log("OK")
});
stream.on('error', function(e)
{
console.log('ERROR during get(): ' + e);
conn.end();
});
console.log("Reading ...");
stream
.pipe(zlib.createGunzip())
.pipe(tar.Parse())
.on("entry", function (e)
{
var filename = e.props["path"];
console.log("filename:" + filename);
if( files[filename] == null )
{
files[filename] = "";
}
e.on("data", function (c)
{
files[filename] += c.toString();
})
});
});
});
})
.connect(21, "ftp.iana.org");