将文件解压到 S3 失败,不知道为什么
untarring files to S3 fails, not sure why
(以下为新信息)
我正在尝试设置一个 lambda 函数,该函数通过解压缩它们并将结果写回 S3 来对上传的 tgz 文件做出反应。解压缩和解包工作正常,但上传到 S3 失败:
/Users/russell/lambda/gzip/node_modules/aws-sdk/lib/s3/managed_upload.js:350
var buf = self.body.read(self.partSize - self.partBuffer.length) ||
^
TypeError: undefined is not a function
at ManagedUpload.fillStream (/Users/russell/lambda/gzip/node_modules/aws-sdk/lib/s3/managed_upload.js:350:25)
at Entry.<anonymous> (/Users/russell/lambda/gzip/node_modules/aws-sdk/lib/s3/managed_upload.js:167:28)
at Entry.emit (events.js:104:17)
at Entry._read (/Users/russell/lambda/gzip/node_modules/tar/lib/entry.js:123:12)
at Entry.end (/Users/russell/lambda/gzip/node_modules/tar/lib/entry.js:82:8)
at Parse._process (/Users/russell/lambda/gzip/node_modules/tar/lib/parse.js:107:13)
at BlockStream.<anonymous> (/Users/russell/lambda/gzip/node_modules/tar/lib/parse.js:47:8)
at BlockStream.emit (events.js:107:17)
at BlockStream._emitChunk (/Users/russell/lambda/gzip/node_modules/tar/node_modules/block-stream/block-stream.js:145:10)
at BlockStream.write (/Users/russell/lambda/gzip/node_modules/tar/node_modules/block-stream/block-stream.js:45:10)
当我写入 S3 时会出现此错误,但如果我将文件本地写入磁盘,它就可以正常工作,因此管道是正确的。
这是演示问题的代码:
var aws = require('aws-sdk');
var s3 = new aws.S3({apiVersion: '2006-03-01'});
var zlib = require('zlib');
var tar = require('tar');
var fstream = require('fstream');
fstream.Reader({'path': 'testdata.tar.gz'})
.pipe(zlib.Unzip())
.pipe(tar.Parse())
.on('entry', function(entry) {
var filename = entry.path;
console.log('got ' + entry.type + ' ' + filename);
if (entry.type == 'File') {
if (1) { // switch between working and nonworking cases
s3.upload({Bucket: 'my_bucket', Key: 'gunzip-test/' + filename, Body: entry}, {},
function(err, data) {
if (err)
console.log('ERROR!');
else
console.log('OK');
});
}
else {
entry.pipe(fstream.Writer({ 'path': '/tmp/mytest/' + filename }));
}
}
});
如果将代码设置为写入 S3,则会失败并出现上述错误,如果将提取的文件写入本地,则会成功。 ENTRY 是一个流,根据 doc 应该在上传 Body 参数中接受。我在 ManagedUpload 中放了一个打印语句,失败的地方,并确认 self.body 是一个流:
var stream = require('stream');
console.log('is it a stream? ' + ((self.body instanceof stream) ? 'yes' : 'no'));
console.log('self.body.read is ' + self.body.read);
returns
$ got File gunzip.js
is it a stream? yes
self.body.read is undefined
我对 aws 和 node.js 很陌生,所以这可能是一个基本问题,但我花了一天时间没有找到它。我使用 unzip 而不是 gzip 进行了上传调用并且它有效 () 谁能指出我在这段代码中做错了什么?
谢谢
我想我理解得更好一些。我把管道分成几块,然后逐一查看。问题是 tar.Parse 使用 fstream 而不是流。如果我查看 .pipe(tar.Parse()) 语句的 return,它是一个流,但它不是 stream.Readable 或 stream.Writable。 fstream没有定义read()方法(它的reader是基于Stream的,不是stream.Readable),所以tar.Parse,它是基于Stream的,也没有.
所以问题的细化是,这是 fstream 中的错误,还是 fstream 不打算成为流?我认为这是一个错误 - 来自自述文件:
"类似于 FS 流,但带有统计信息,并支持目录和
符号链接,以及普通文件。另外,您可以使用它来设置
文件的统计信息,即使您不更改其内容或创建
符号链接等
你的 body 变量是一个 Stream 对象,在这种情况下你需要使用 .toString()
var aws = require('aws-sdk');
var s3 = new aws.S3({apiVersion: '2006-03-01'});
var zlib = require('zlib');
var tar = require('tar');
var fstream = require('fstream');
fstream.Reader({'path': 'testdata.tar.gz'})
.pipe(zlib.Unzip())
.pipe(tar.Parse())
.on('entry', function(entry) {
var filename = entry.path;
console.log('got ' + entry.type + ' ' + filename);
if (entry.type == 'File') {
if (1) { // switch between working and nonworking cases
s3.upload({Bucket: 'my_bucket', Key: 'gunzip-test/' + filename, Body: entry.toString()}, {},
function(err, data) {
if (err)
console.log('ERROR!');
else
console.log('OK');
});
}
else {
entry.pipe(fstream.Writer({ 'path': '/tmp/mytest/' + filename }));
}
}
});
在我的例子中 运行 通过 stream.PassThrough 的流帮助了。
var PassThrough = require('stream').PassThrough;
var stream = getStreamSomeHow();
var passthrough = new PassThrough();
stream.pipe(passthrough);
s3.upload({...,Body:passthrough}) //
(以下为新信息) 我正在尝试设置一个 lambda 函数,该函数通过解压缩它们并将结果写回 S3 来对上传的 tgz 文件做出反应。解压缩和解包工作正常,但上传到 S3 失败:
/Users/russell/lambda/gzip/node_modules/aws-sdk/lib/s3/managed_upload.js:350
var buf = self.body.read(self.partSize - self.partBuffer.length) ||
^
TypeError: undefined is not a function
at ManagedUpload.fillStream (/Users/russell/lambda/gzip/node_modules/aws-sdk/lib/s3/managed_upload.js:350:25)
at Entry.<anonymous> (/Users/russell/lambda/gzip/node_modules/aws-sdk/lib/s3/managed_upload.js:167:28)
at Entry.emit (events.js:104:17)
at Entry._read (/Users/russell/lambda/gzip/node_modules/tar/lib/entry.js:123:12)
at Entry.end (/Users/russell/lambda/gzip/node_modules/tar/lib/entry.js:82:8)
at Parse._process (/Users/russell/lambda/gzip/node_modules/tar/lib/parse.js:107:13)
at BlockStream.<anonymous> (/Users/russell/lambda/gzip/node_modules/tar/lib/parse.js:47:8)
at BlockStream.emit (events.js:107:17)
at BlockStream._emitChunk (/Users/russell/lambda/gzip/node_modules/tar/node_modules/block-stream/block-stream.js:145:10)
at BlockStream.write (/Users/russell/lambda/gzip/node_modules/tar/node_modules/block-stream/block-stream.js:45:10)
当我写入 S3 时会出现此错误,但如果我将文件本地写入磁盘,它就可以正常工作,因此管道是正确的。
这是演示问题的代码:
var aws = require('aws-sdk');
var s3 = new aws.S3({apiVersion: '2006-03-01'});
var zlib = require('zlib');
var tar = require('tar');
var fstream = require('fstream');
fstream.Reader({'path': 'testdata.tar.gz'})
.pipe(zlib.Unzip())
.pipe(tar.Parse())
.on('entry', function(entry) {
var filename = entry.path;
console.log('got ' + entry.type + ' ' + filename);
if (entry.type == 'File') {
if (1) { // switch between working and nonworking cases
s3.upload({Bucket: 'my_bucket', Key: 'gunzip-test/' + filename, Body: entry}, {},
function(err, data) {
if (err)
console.log('ERROR!');
else
console.log('OK');
});
}
else {
entry.pipe(fstream.Writer({ 'path': '/tmp/mytest/' + filename }));
}
}
});
如果将代码设置为写入 S3,则会失败并出现上述错误,如果将提取的文件写入本地,则会成功。 ENTRY 是一个流,根据 doc 应该在上传 Body 参数中接受。我在 ManagedUpload 中放了一个打印语句,失败的地方,并确认 self.body 是一个流:
var stream = require('stream');
console.log('is it a stream? ' + ((self.body instanceof stream) ? 'yes' : 'no'));
console.log('self.body.read is ' + self.body.read);
returns
$ got File gunzip.js
is it a stream? yes
self.body.read is undefined
我对 aws 和 node.js 很陌生,所以这可能是一个基本问题,但我花了一天时间没有找到它。我使用 unzip 而不是 gzip 进行了上传调用并且它有效 (
谢谢
我想我理解得更好一些。我把管道分成几块,然后逐一查看。问题是 tar.Parse 使用 fstream 而不是流。如果我查看 .pipe(tar.Parse()) 语句的 return,它是一个流,但它不是 stream.Readable 或 stream.Writable。 fstream没有定义read()方法(它的reader是基于Stream的,不是stream.Readable),所以tar.Parse,它是基于Stream的,也没有.
所以问题的细化是,这是 fstream 中的错误,还是 fstream 不打算成为流?我认为这是一个错误 - 来自自述文件:
"类似于 FS 流,但带有统计信息,并支持目录和 符号链接,以及普通文件。另外,您可以使用它来设置 文件的统计信息,即使您不更改其内容或创建 符号链接等
你的 body 变量是一个 Stream 对象,在这种情况下你需要使用 .toString()
var aws = require('aws-sdk');
var s3 = new aws.S3({apiVersion: '2006-03-01'});
var zlib = require('zlib');
var tar = require('tar');
var fstream = require('fstream');
fstream.Reader({'path': 'testdata.tar.gz'})
.pipe(zlib.Unzip())
.pipe(tar.Parse())
.on('entry', function(entry) {
var filename = entry.path;
console.log('got ' + entry.type + ' ' + filename);
if (entry.type == 'File') {
if (1) { // switch between working and nonworking cases
s3.upload({Bucket: 'my_bucket', Key: 'gunzip-test/' + filename, Body: entry.toString()}, {},
function(err, data) {
if (err)
console.log('ERROR!');
else
console.log('OK');
});
}
else {
entry.pipe(fstream.Writer({ 'path': '/tmp/mytest/' + filename }));
}
}
});
在我的例子中 运行 通过 stream.PassThrough 的流帮助了。
var PassThrough = require('stream').PassThrough;
var stream = getStreamSomeHow();
var passthrough = new PassThrough();
stream.pipe(passthrough);
s3.upload({...,Body:passthrough}) //