Как преобразовать массив байтов в его числовое значение (Java)?

В настройке Cloud Functions действительно произошли серьезные изменения, которые вызвали эту проблему. Это связано с тем, как работает промежуточное ПО, которое применяется ко всем приложениям Express (включая приложение по умолчанию), используемым для обслуживания функций HTTPS. По сути, облачные функции будут анализировать тело запроса и решать, что с ним делать, оставляя необработанное содержимое тела в буфере в req.rawBody. Вы можете использовать это для непосредственного анализа вашего многокомпонентного контента, но вы не можете сделать это с помощью промежуточного программного обеспечения (например, multer).

Вместо этого вы можете использовать модуль под названием busboy для непосредственной работы с необработанным содержимым тела. Он может принять буфер rawBody и перезвонит вам с найденными файлами. Вот пример кода, который будет перебирать весь загруженный контент, сохранять его как файлы, а затем удалять их. Вы, очевидно, захотите сделать что-то более полезное.

const path = require('path');
const os = require('os');
const fs = require('fs');
const Busboy = require('busboy');

exports.upload = functions.https.onRequest((req, res) => {
    if (req.method === 'POST') {
        const busboy = new Busboy({ headers: req.headers });
        // This object will accumulate all the uploaded files, keyed by their name
        const uploads = {}

        // This callback will be invoked for each file uploaded
        busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
            console.log(`File [${fieldname}] filename: ${filename}, encoding: ${encoding}, mimetype: ${mimetype}`);
            // Note that os.tmpdir() is an in-memory file system, so should only 
            // be used for files small enough to fit in memory.
            const filepath = path.join(os.tmpdir(), fieldname);
            uploads[fieldname] = { file: filepath }
            console.log(`Saving '${fieldname}' to ${filepath}`);
            file.pipe(fs.createWriteStream(filepath));
        });

        // This callback will be invoked after all uploaded files are saved.
        busboy.on('finish', () => {
            for (const name in uploads) {
                const upload = uploads[name];
                const file = upload.file;
                res.write(`${file}\n`);
                fs.unlinkSync(file);
            }
            res.end();
        });

        // The raw bytes of the upload will be in req.rawBody.  Send it to busboy, and get
        // a callback when it's finished.
        busboy.end(req.rawBody);
    } else {
        // Client error - only support POST
        res.status(405).end();
    }
})

Помните, что файлы, сохраненные во временном пространстве, занимают память, поэтому их размеры должны быть ограничены до 10 МБ. Для более крупных файлов вы должны загрузить их в облачное хранилище и обработать их с помощью триггера хранилища.

Также имейте в виду, что выбор промежуточного программного обеспечения по умолчанию, добавляемый Cloud Functions, в настоящее время не добавляется в локальный эмулятор через firebase serve. Так что этот пример не будет работать (rawBody не будет доступен) в этом случае.

Команда работает над обновлением документации, чтобы лучше понять, что происходит во время запросов HTTPS, отличающихся от стандартного приложения Express.

86
задан Mnementh 7 August 2009 в 07:26
поделиться

3 ответа

Предполагая, что первый байт является младшим байтом:

long value = 0;
for (int i = 0; i < by.length; i++)
{
   value += ((long) by[i] & 0xffL) << (8 * i);
}

Is первый байт - самый значимый, тогда он немного отличается:

long value = 0;
for (int i = 0; i < by.length; i++)
{
   value = (value << 8) + (by[i] & 0xff);
}

Заменить long на BigInteger , если у вас больше 8 байт.

Спасибо Аарону Дигулле за исправление моих ошибок .

long value = 0;
for (int i = 0; i < by.length; i++)
{
   value += ((long) by[i] & 0xffL) << (8 * i);
}

Является ли первый байт наиболее значимым, тогда он немного отличается:

long value = 0;
for (int i = 0; i < by.length; i++)
{
   value = (value << 8) + (by[i] & 0xff);
}

Замените long на BigInteger , если у вас больше 8 байтов.

Спасибо Аарону Дигулле за исправление моих ошибок.

long value = 0;
for (int i = 0; i < by.length; i++)
{
   value += ((long) by[i] & 0xffL) << (8 * i);
}

Является ли первый байт наиболее значимым, тогда он немного отличается:

long value = 0;
for (int i = 0; i < by.length; i++)
{
   value = (value << 8) + (by[i] & 0xff);
}

Замените long на BigInteger , если у вас больше 8 байтов.

Спасибо Аарону Дигулле за исправление моих ошибок.

102
ответ дан 24 November 2019 в 07:57
поделиться

Для выполнения преобразования можно использовать Buffer , которые предоставляются как часть java.nio пакета.

Здесь Исходный массив byte [] имеет длину 8, что соответствует размеру, соответствующему значению long .

Во-первых, массив byte [] упакован в ByteBuffer , а затем вызывается метод ByteBuffer.getLong для получения значения long :

ByteBuffer bb = ByteBuffer.wrap(new byte[] {0, 0, 0, 0, 0, 0, 0, 4});
long l = bb.getLong();

System.out.println(l);

Result

4

Я бы хотел поблагодарить dfa за указание метода ByteBuffer.getLong в комментариях.


Хотя он может быть неприменим в этой ситуации, красота Buffer заключается в том, чтобы взглянуть на массив с несколькими значениями.

Например, если у нас есть 8-байтовый массив,и мы хотели видеть его как два значения int , мы могли бы обернуть массив byte [] в ByteBuffer , который рассматривается как IntBuffer и получить значения с помощью IntBuffer.get :

ByteBuffer bb = ByteBuffer.wrap(new byte[] {0, 0, 0, 1, 0, 0, 0, 4});
IntBuffer ib = bb.asIntBuffer();
int i0 = ib.get(0);
int i1 = ib.get(1);

System.out.println(i0);
System.out.println(i1);

Результат:

1
4
112
ответ дан 24 November 2019 в 07:57
поделиться

Если это 8-байтовое числовое значение, вы можете попробовать:

BigInteger n = new BigInteger(byteArray);

Если это символьный буфер UTF-8, вы можете попробовать:

BigInteger n = new BigInteger(new String(byteArray, "UTF-8"));
16
ответ дан 24 November 2019 в 07:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: