Как преобразовать возвращаемый байтовый массив Bigtable HBase API в целое или с плавающей точкой в ​​nodeJS? - PullRequest
0 голосов
/ 12 октября 2018

Я записываю данные из потока данных в bigtable, и мне нужно извлечь данные из NodeJS, но понял, что данные находятся в байтовом массиве.Как мне конвертировать обратно в целое число или число с плавающей запятой?

Ключ "\ u0000 \ u0000 \ u0000 \ u0000" изначально был 0, но я никогда не мог заставить его правильно выводиться в моем коде nodeJS.

Я пробовал следующие методы, используяBuffer, bin2string, byteArrayToLong, но ни один из них не работал правильно.Ниже приведен код для запроса данных.

async function query(table, start, end) {
  return new Promise((resolve, reject) => {
    table.createReadStream({
      start: start,
      end: end
    }).on('data', function(row) {
        for(var key in row.data.ch){
            console.log(JSON.stringify(key));               // Output: "\u0000\u0000\u0000\u0000"
            console.log(`bin2string: ${bin2string(key)}`);  // Output: bin2string:

            let keybuf = Buffer.from(key);
            console.log(keybuf);                            // Output: <Buffer 00 00 00 00>
            console.log(keybuf.toString('utf8'));           // Output:
            const utf16Buffer = Buffer.from(key,'utf16le'); // Output: <Buffer 00 00 00 00 00 00 00 00>
            console.log(utf16Buffer);
            console.log(utf16Buffer.toString());            // Output:
            console.log(byteArrayToLong(key));              // Output: NaN
        }
      // Nothing to do with data
      // We can measure the time needed to get the first row
    }).on('end', function(){
      resolve();
    });  
  });
}

function bin2string(array){
    var result = "";
    for(var i = 0; i < array.length; ++i){
        result+= (String.fromCharCode(array[i]));
    }
    return result;
}

function byteArrayToLong (byteArray){
    var value =0;
    for(var i=byteArray.length-1; i>=0; i--){
        value = value*256 + byteArray[i];
    }
    return value;
}

Ответы [ 2 ]

0 голосов
/ 08 ноября 2018

Для целых чисел будет работать следующая функция.

function byteToInt(x){
    let val=0;
    for (let i=0; i<x.length; ++i) {        
        val+=x[i];        
        if(i<x.length-1) val = val << 8;
    }
    return val;
}

Для float NodeJS уже предоставляет метод для чтения из буфера:

let buf = Buffer.from(value, 'binary');
let num = buf.readFloatBE(0);

Возможно также использоватьниже, в зависимости от порядкового номера и количества битов:

buf.readInt8 (смещение)

buf.readInt16BE (смещение)

buf.readInt16LE (смещение)

buf.readInt32BE (смещение)

buf.readInt32LE (смещение)

0 голосов
/ 18 октября 2018

У меня нет полного ответа на ваш вопрос, но у меня есть несколько указателей.

Облачные числа Bigtable - это все "64-разрядное целое число, закодированное как 8-байтовое значение с прямым порядком байтов" (см.* здесь * 1004).Лонды Node.js "endian-ness" зависят от системы (см. здесь ).PHP имеет аналогичную проблему с Cloud Bigtable (см. здесь ).

В Java все числовые значения имеют порядковый номер.Класс HBase Bytes выполняет все преобразования между числами и байтами ( исходный код ) и может предоставить некоторые подсказки.

Возможно, было бы неправильно опубликовать проблему на https://github.com/googleapis/nodejs-bigtable/issues, чтобы получить лучшее решение.

...