使用 IBM Cloud Function 读取 gzip 文件 (.gz) 时出现问题(操作:Node.js 12)

An issue with reading a gzipped file (.gz) with IBM Cloud Function (Action: Node.js 12)

我可以使用下面提到的代码 (node --version: v14.15.0) 在本地机器上读取 data.json.gz 文件。但是,当我尝试在 IBM Cloud 中使用相同的操作 (Node.js 12) 从 Object Store Bucket 读取相同的文件时,出现以下错误 ["stderr: ERROR: undefined - input_buf.on 不是函数"].

我是 NodeJS 的新手;有人可以帮助确定这里的问题吗? 感谢您的支持。

适用于本地机器的代码 (Windows 10):

function decompressFile(filename) {
    var fs = require("fs"),
        zlib = require("zlib"),
    var input = fs.createReadStream(filename);
    var data = [];

    input.on('data', function(chunk){
        data.push(chunk);
    }).on('end', function(){
        var buf = Buffer.concat(data);
        zlib.gunzip(buf, function(err, buffer) {
            if (!err) {
                var dataString = buffer.toString()
                console.log(dataString, dataString+'\n');
                var dataJSON = JSON.parse(dataString.toString('utf8'));
            }else{
                console.log(err);
            }
        });
    });
}

decompressFile("data.json.gz");

不适用于 IBM Cloud Function 和 Object Store Bucket 的代码:

 // Get file contents of gzipped item
async function getGzippedItem(cosClient, bucketName, itemName) { // <<< async keyword added
    const fs = require('fs');
    const zlib = require('zlib');
   
    return await cosClient.getObject({  // <<< turned into assignment with await
        Bucket: bucketName,
        Key: itemName
    }).promise() 
        .then((instream=fs.createReadStream(itemName)) => {
            if (instream != null) {         
                var data = [];
                var input_buf = instream.Body

    input_buf.on('data', function(chunk){
        data.push(chunk);
    }).on('end', function() {
        var buf = Buffer.concat(data);

        zlib.gunzip(buf, function (err, buffer) {
            if (!err) {
                var dataString = buffer.toString()
                var dataJSON = JSON.parse(dataString.toString('utf8'));

            } else {
                console.log(err);
            }
        });


    });
                return buf
                }
        })
        .catch((e) => {
            console.error(`ERROR: ${e.code} - ${e.message}\n`);
        }); 
};


async function main(params) {

bucketName = 'bucket'
itemName = 'data.json.gz'

var ibm = require('ibm-cos-sdk');
var util = require('util');
var fs = require('fs');

// Initializing configuration
const myCOS = require('ibm-cos-sdk');

var config = {
    endpoint: 'endpoint',
    apiKeyId: 'apiKeyId',
    ibmAuthEndpoint: 'ibmAuthEndpoint',
    serviceInstanceId: 'serviceInstanceId',
};

var cosClient = new myCOS.S3(config);

gzippedItemContent = await getGzippedItem(cosClient, bucketName, itemName) // <<< await keyword added
console.log(">>>>>>>>>>>>>>>: ", typeof gzippedItemContent, gzippedItemContent )

}

消息告诉您,您的 input_buf 对象不是您期望的类型。 createReadStream() 调用的结果只是 stream:

[Stream] the readable stream object that can be piped or read from (by registering 'data' event listeners).

所以你应该可以直接访问这个值 (不声明 var input_buf = instream.Body):

   var getObjectStream = cosClient.getObject({
    Bucket: 'BUCKET',
    Key: 'KEY'
    }).createReadStream();
   
   getObjectStream.on('data', function(c) {
      data += c.toString();
    });

看看ibm-cos-sdk-js项目的test section,它描述了如何使用API。