Вопрос или проблема
Я пытаюсь сохранить буфер (файл, загруженный из формы) в хранилище Google Cloud, но, похоже, что SDK Google для Node.js позволяет загружать только файлы с заданным путем (потоки чтения/записи).
Вот что я использовал для AWS (S3) – есть ли что-то подобное в SDK Google для Node.js?:
var fileContents = new Buffer('buffer');
var params = {
Bucket: //имя корзины
Key: //имя файла
ContentType: // Установить тип содержимого
Body: fileContents
};
s3.putObject(params, function(err, data) {
// Сделать что-то
});
Единственный способ, который я нашел до сих пор, это записать буфер на диск, загрузить файл с помощью SDK (указав путь к новому файлу), а затем удалить файл после успешной загрузки – недостаток этого способа заключается в том, что весь процесс значительно медленнее, и кажется, что использование Google Storage нецелесообразно. Есть ли какое-либо обходное решение / способ загрузить буфер?
.save
спасет ситуацию! Вот небольшой код, где я сохраняю свой “pdf”, который я создал.
https://googleapis.dev/nodejs/storage/latest/File.html#save
const { Storage } = require("@google-cloud/storage");
const gc = new Storage({
keyFilename: path.join(__dirname, "./путь к вашему .json сервисному аккаунту"),
projectId: "ваш идентификатор проекта",
});
const file = gc.bucket(bucketName).file("tester.pdf");
file.save(pdf, (err) => {
if (!err) {
console.log("отлично");
} else {
console.log("ошибка " + err);
}
});
У нас есть проблема с тем, чтобы сделать это проще: https://github.com/GoogleCloudPlatform/gcloud-node/issues/1179
Но пока вы можете попробовать:
file.createWriteStream()
.on('error', function(err) {})
.on('finish', function() {})
.end(fileContents);
На самом деле это просто:
let remotePath="some/key/to/store.json";
let localReadStream = new stream.PassThrough();
localReadStream.end(JSON.stringify(someObject, null, ' '));
let remoteWriteStream = bucket.file(remotePath).createWriteStream({
metadata : {
contentType : 'application/json'
}
});
localReadStream.pipe(remoteWriteStream)
.on('error', err => {
return callback(err);
})
.on('finish', () => {
return callback();
});
Следующий фрагмент взят из примера Google. Пример предполагает, что вы использовали multer или что-то подобное и можете получить доступ к файлу через req.file
. Вы можете отправить файл в облачное хранилище, используя промежуточное ПО, которые выглядит следующим образом:
function sendUploadToGCS (req, res, next) {
if (!req.file) {
return next();
}
const gcsname = Date.now() + req.file.originalname;
const file = bucket.file(gcsname);
const stream = file.createWriteStream({
metadata: {
contentType: req.file.mimetype
},
resumable: false
});
stream.on('error', (err) => {
req.file.cloudStorageError = err;
next(err);
});
stream.on('finish', () => {
req.file.cloudStorageObject = gcsname;
file.makePublic().then(() => {
req.file.cloudStoragePublicUrl = getPublicUrl(gcsname);
next();
});
});
stream.end(req.file.buffer);
}
У меня есть работающий подход:
const destFileName = `someFolder/${file.name}`;
const fileCloud = this.storage.bucket(bucketName).file(destFileName);
fileCloud.save(file.buffer, {
contentType: file.mimetype
}, (err) => {
if (err) {
console.log("ошибка");
}
});
Ответ или решение
Для загрузки буфера (например, файла, загруженного через форму) в Google Cloud Storage, вы можете использовать клиентскую библиотеку для Node.js, как это сделано в AWS S3, однако имеется несколько подходов для работы с буферами.
Вот несколько способов загрузки буфера в Google Cloud Storage:
1. Использование метода save
Вы можете воспользоваться методом save
класса File
, который позволяет загружать содержимое буфера напрямую в Cloud Storage, как в примере ниже:
const { Storage } = require('@google-cloud/storage');
const path = require('path');
const gc = new Storage({
keyFilename: path.join(__dirname, './path to your service account .json'),
projectId: 'your project id',
});
const bucketName = 'your-bucket-name';
const fileName = 'tester.pdf'; // Имя файла, под которым он будет храниться
const bufferContents = Buffer.from('ваш буфер здесь', 'utf8'); // Создание буфера
const file = gc.bucket(bucketName).file(fileName);
file.save(bufferContents, {
contentType: 'application/pdf' // Установите нужный MIME-тип
}, (err) => {
if (err) {
console.error('Ошибка при загрузке файла:', err);
} else {
console.log('Файл успешно загружен!');
}
});
2. Использование createWriteStream
Если вам нужно больше контроля, вы можете использовать createWriteStream
, чтобы передавать данные в виде потока. Например:
const { Storage } = require('@google-cloud/storage');
const storage = new Storage({
keyFilename: path.join(__dirname, './path to your service account .json'),
projectId: 'your project id',
});
const bucketName = 'your-bucket-name';
const remotePath = 'some/path/to/file.txt'; // Путь, по которому файл будет храниться в Cloud Storage
const bufferContents = Buffer.from('ваш буфер здесь', 'utf8');
const file = storage.bucket(bucketName).file(remotePath);
const stream = file.createWriteStream({
metadata: {
contentType: 'text/plain' // Установите нужный MIME-тип
},
});
stream.on('error', err => {
console.error('Ошибка при записи в поток:', err);
});
stream.on('finish', () => {
console.log('Файл успешно загружен!');
});
// Завершаем запись буфера в поток
stream.end(bufferContents);
3. Использование pipe()
с PassThrough
Другой способ заключается в использовании объекта PassThrough
из stream
, который позволяет передавать данные в поток:
const { Storage } = require('@google-cloud/storage');
const stream = require('stream');
const storage = new Storage({
keyFilename: path.join(__dirname, './path to your service account .json'),
projectId: 'your project id',
});
const bucketName = 'your-bucket-name';
const remotePath = 'some/path/to/file.json'; // Имя файла в облаке
const jsonObject = { key: 'value' }; // Пример объекта, который вы хотите сохранить
const localReadStream = new stream.PassThrough();
localReadStream.end(JSON.stringify(jsonObject)); // Преобразуем объект в JSON
const remoteWriteStream = storage.bucket(bucketName).file(remotePath).createWriteStream({
metadata: {
contentType: 'application/json' // Установите нужный MIME-тип
}
});
localReadStream.pipe(remoteWriteStream)
.on('error', err => {
console.error('Ошибка при загрузке:', err);
})
.on('finish', () => {
console.log('Файл успешно загружен!');
});
Заключение
Google Cloud Storage предлагает несколько удобных методов для загрузки буферов, которые позволяют избежать временной потери, связанной с записью на диск. Используйте вышеописанные методы в зависимости от ваших требований и дополнительных возможностей, которые вы хотите реализовать при работе с потоками данных.