我正在使用优秀的Request库来下载Node中的文件,这是我正在使用的一个小命令行工具。请求完全适用于拉入单个文件,完全没有问题,但它不适用于ZIP。
例如,我尝试下载位于网址的Twitter Bootstrap存档:
http://twitter.github.com/bootstrap/assets/bootstrap.zip
代码的相关部分是:
var fileUrl = "http://twitter.github.com/bootstrap/assets/bootstrap.zip";
var output = "bootstrap.zip";
request(fileUrl, function(err, resp, body) {
if(err) throw err;
fs.writeFile(output, body, function(err) {
console.log("file written!");
}
}
我已尝试将编码设置为"二进制"也没有运气。实际的拉链大约是74KB,但是当通过上面的代码下载它是~134KB并且双击Finder来提取它时,我收到错误:
无法提取" bootstrap"进入" nodetest" (错误21 - 是目录)
我觉得这是一个编码问题,但不知道从哪里开始。
答案 0 :(得分:40)
是的,问题在于编码。等待整个传输完成时body
默认强制转换为字符串。您可以通过将request
选项设置为Buffer
来告诉encoding
给您一个null
:
var fileUrl = "http://twitter.github.com/bootstrap/assets/bootstrap.zip";
var output = "bootstrap.zip";
request({url: fileUrl, encoding: null}, function(err, resp, body) {
if(err) throw err;
fs.writeFile(output, body, function(err) {
console.log("file written!");
});
});
另一个更优雅的解决方案是使用pipe()
将响应指向文件可写流:
request('http://twitter.github.com/bootstrap/assets/bootstrap.zip')
.pipe(fs.createWriteStream('bootstrap.zip'))
.on('close', function () {
console.log('File written!');
});
一个班轮总是获胜:)
pipe()
返回目标流(本例中为WriteStream),因此您可以收听其close
事件,以便在写入文件时收到通知。
答案 1 :(得分:0)
我正在搜索一个需要zip的函数,并且无需在服务器内部创建任何文件就将其解压缩,这是我的TypeScript函数,它使用JSZIP module和Request:
let bufs : any = [];
let buf : Uint8Array;
request
.get(url)
.on('end', () => {
buf = Buffer.concat(bufs);
JSZip.loadAsync(buf).then((zip) => {
// zip.files contains a list of file
// chheck JSZip documentation
// Example of getting a text file : zip.file("bla.txt").async("text").then....
}).catch((error) => {
console.log(error);
});
})
.on('error', (error) => {
console.log(error);
})
.on('data', (d) => {
bufs.push(d);
})