Open jiulanrensan opened 10 months ago
sdk本身不会转译buffer类型
最近在开发处理 .npy 文件
发现使用 obs SDK
取回的文件内容无法解析
上传 .npy 文件到 obs
使用 SDK 取回
async function loadNpy() {
const result = await sourceObs.getObject({
Bucket: 'demo',
Key: '001.npy',
ResponseHook(res) {
res.on('data', (chunk) => {
console.log('res.data[0]', chunk.readUint8(0));
console.log('res.data[1]', chunk.readUint8(1));
console.log('res.data[2]', chunk.readUint8(2));
})
}
})
const content = result.InterfaceResult.Content;
const buffer = Buffer.from(content, 'binary');
console.log('content[0]', buffer.readUInt8(0));
console.log('content[1]', buffer.readUInt8(1));
console.log('content[2]', buffer.readUInt8(2));
}
输出
res.data[0] 147 <--
res.data[1] 78
res.data[2] 85
content[0] 253 <--
content[1] 78
content[2] 85
第一个 byte 从 147 变为 253 了
opt.InterfaceResult[key] = body.toString('utf8')
// utils.js
Utils.prototype.getRequest
serverback.on('end',
...
if(body.length > 0 && ('data' in model)){
...
if(model.data.type === 'body'){
....
opt.InterfaceResult[key] = body.toString('utf8');
// 截取自 .npy 文件
// Python numpy 导出数值文件
const data = [147,78,85,77,80,89]
const buffer = Buffer.from(data)
const utf8String = buffer.toString('utf8')
const buffer1 = Buffer.from(utf8String, 'binary')
let bytes = []
let bytes1 = []
for(let i = 0; i < buffer.byteLength; i++) {
bytes.push(buffer.readUInt8(i))
bytes1.push(buffer1.readUInt8(i))
}
console.log(bytes)
console.log(bytes1)
// [ 147, 78, 85, 77, 80, 89 ]
// [ 253, 78, 85, 77, 80, 89 ]
临时解决方案 从 saveAsStream 方式中转
ObsClient.prototype.getObjectBuffer = function(param, callback) {
function isFunction(a) {
return typeof a === 'function';
}
const addParam = {
// 默认会先转字符串 utf8
// 导致读取首字节错误
// 147 -> 253
// @see https://github.com/huaweicloud/huaweicloud-sdk-nodejs-obs/blob/5cc75e293fd7481d581e5edfefb58825c7b5ced3/lib/utils.js#L1604
// 这里手工 从 stream 读取
SaveAsStream : true,
};
const _param = param && !isFunction(param)
? {
...param,
...addParam,
}
: addParam;
const _cb = isFunction(param)
? param
: isFunction(callback)
? callback
: undefined;
const p = this.getObject(_param)
.then(result => {
if (result.CommonMsg.Status < 300) {
return new Promise((resolve, reject) => {
const stream = result.InterfaceResult.Content;
let buffers = []
stream.on('data', (chunk) => {
buffers.push(chunk);
})
stream.on('end', () => {
resolve(Buffer.concat(buffers))
})
stream.on('error', reject)
})
} else {
throw result;
}
})
.then(buffer => {
if (_cb) {
_cb(null, buffer);
} else {
return buffer;
}
})
.catch(err => {
if (_cb) {
_cb(err)
} else {
throw err;
}
})
return _cb ? undefined : p;
}
官方文档返回结果的Content如下:
但实际上sdk返回的为string类型,查sdk代码,发现在响应处对buffer对象做了
body.toString('utf8')
处理问题: