NodeJS NextJS文件成功上传到Google Cloud Storage,但总是上传0字节文件-使用强大的

68bkxrlz  于 2022-11-29  发布在  Node.js
关注(0)|答案(1)|浏览(216)

我尝试在nextJS中实现一个文件加载,并将文件流到谷歌云存储。我使用的是formidab。Formidable给了我一个文件路径、新文件名、文件大小等,但当文件出现在谷歌存储中时,它的字节数为零。这就像是位置正在创建,但我的blob流实际上并没有将文件推到那里。
下面是我的api路径的代码。有什么想法吗?

import { Storage } from "@google-cloud/storage";
import formidable from '../../lib/formidable-serverless'

export const config = {
  api: {
    bodyParser: false,
  },
};

export default async function handler(req, res) {
  console.log('req')
  const storage = new Storage({
    projectId: process.env.GOOGLE_SERVICE_ID,
    client_email: process.env.GOOGLE_CLIENT_EMAIL,
    private_key: process.env.GOOGLE_SERVICE_KEY,
  });
  const data = await new Promise(function(resolve, reject) { 
    const form = new formidable.IncomingForm();
    form.keepExtensions = true;
    form.parse(req, function(err, fields, files) {
      if (err) return reject(err);
      resolve({ fields, files });
    });
  });
  const file = data.files.file
    try {
      const bucket = storage.bucket(process.env.GCS_BUCKET)
      const blob = bucket.file(file.originalFilename);
     
      const blobStream = blob.createWriteStream({
        resumable: false,
      });
    
      blobStream.on("error", (err) => {
        console.log('ERR', err.message)
        res.status(500).send({ message: err.message });
      });
  
      blobStream.on("finish", async () => {
        const publicURL = `https://storage.googleapis.com/${bucket.name}/${blob.name}`
      ;
        try {
          await blob.makePublic();
        } catch {
          return res.status(500).send({
            message: `Uploaded the file successfully: ${file.newFilename}, but public access is denied!`,
            url: publicURL,
          });
        }
  
        res.status(200).send({
          message: "Uploaded the file successfully: " + file.newFilename,
          url: publicURL,
        });
      });
      blobStream.end();
    } catch (err) {
      if (err.code == "LIMIT_FILE_SIZE") {
        console.log('ERR', err.message)
        return res.status(500).send({
          message: "File size cannot be larger than 25MB!",
        });
      }
  
      res.status(500).send({
        message: `Could not upload the file: ${file.newFilename}. ${err}`,
      });
   }

这是我的blobstream在创建后的外观。

Writable {
  _writableState: WritableState {
    objectMode: false,
    highWaterMark: 16384,
    finalCalled: false,
    needDrain: false,
    ending: false,
    ended: false,
    finished: false,
    destroyed: false,
    decodeStrings: true,
    defaultEncoding: 'utf8',
    length: 0,
    writing: false,
    corked: 0,
    sync: true,
    bufferProcessing: false,
    onwrite: [Function: bound onwrite],
    writecb: null,
    writelen: 0,
    afterWriteTickInfo: null,
    buffered: [],
    bufferedIndex: 0,
    allBuffers: true,
    allNoop: true,
    pendingcb: 0,
    prefinished: false,
    errorEmitted: false,
    emitClose: true,
    autoDestroy: true,
    errored: null,
    closed: false
  },

这是解决了令人生畏的承诺后文件的样子。那里也有一个可写的流。

PersistentFile {
  _events: [Object: null prototype] { error: [Function (anonymous)] },
  _eventsCount: 1,
  _maxListeners: undefined,
  lastModifiedDate: 2022-11-22T14:54:26.597Z,
  filepath: '/var/folders/yb/l636l56d7ng731jp24crv6lw0000gn/T/9e8fb9b8b1e0740b2622b990b',
  newFilename: '9e8fb9b8b1e0740b2622b990b',
  originalFilename: '17.mp3',
  mimetype: 'audio/mpeg',
  hashAlgorithm: false,
  size: 7020751,
  _writeStream: WriteStream {
    _writableState: WritableState {
      objectMode: false,
      highWaterMark: 16384,
      finalCalled: true,
      needDrain: true,
      ending: true,
      ended: true,
      finished: true,
      destroyed: true,
      decodeStrings: true,
      defaultEncoding: 'utf8',
      length: 0,
      writing: false,...
}

当我创建我的blob时,我是否不知何故没有将我的文件传递到写流中?

yvfmudvl

yvfmudvl1#

作为社区wiki回答,
这可以通过实现一个readStream来解决,该readStream读取文件路径,在writestream开始之前,该路径临时存储了文件。

createReadStream(file.filepath) 
.pipe(blob.createWriteStream(file.originalFilename, file.mimetype))  
console.log('blobstream', blobStream) 
.on("error", (err) => { console.log('ERR', err.message) 
res.status(500).send({ message: err.message 
});
}) 
.on("finish", async () => { // create a url to access file ...

相关问题