如何在Node中将文件流保存为文件夹中的文件

4
当我上传一个文件时,服务器会返回一个包含streamfilenamemimetypeencoding的响应。我不知道如何将该流保存为服务器上的文件。我尝试使用fs.createReadStream,但是我无法弄清楚下一步应该怎么做,比如如何将其放入./uploads文件夹中?
 { stream:
  FileStream {
    _readableState: [Object],
    readable: true,
    domain: null,
    _events: [Object],
    _eventsCount: 2,
    _maxListeners: undefined,
    truncated: false,
    _read: [Function] },
 filename: 'test-sample.xlsx',
 mimetype: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
 encoding: '7bit' } }

1
嗨Woopi,看看这个帖子=> https://dev59.com/U5Pea4cB1Zd3GeqP-ROy,看看它是否有帮助。 - David R
2个回答

11

这是对我有效的代码。我正在使用Apollo Server和Graphql,而'singleUpload'是我为上传图像创建的解析器。

const path = require("path");
const { createWriteStream } = require("fs");

这两个导入已经包含在节点包中,因此您不需要单独安装它们。

singleUpload: async (_, { file }) => {
      const { createReadStream, filename, mimetype, encoding } = await file;

      await new Promise((res) =>
        createReadStream()
          .pipe(
            createWriteStream(
              path.join(__dirname, "../../uploads/images", filename)
            )
          )
          .on("close", res)
      );

      return true;
    }
  }
};

'file'是我从<input type="file"/>转发的图像文件。前端的apollo-upload-client会自动将流存储在'createReadStream()'中,我可以从传入的文件promise中分解出它。然后使用'createWriteStream'管道传输该流并将其存储在我在服务器上指定的路径中。createWriteStream函数中的路径是相对于您当前目录的,服务器将在运行时查找此文件夹,因此请确保它存在。

最后一件事,如果您直接从服务器向前端提供这些图像,请确保在主index.js服务器文件中包含以下行。

app.use("/images", express.static(path.join(__dirname, "./uploads/images")));

5
我在这个问题上得到了apollo-upload-server的作者的帮助。以防有人遇到此问题,以下是将流保存到文件的方法:
const storeFS = ({ stream, filename }) => {
  const uploadDir = './uploads';
  const path = `${uploadDir}/${filename}`;
  return new Promise((resolve, reject) =>
    stream
      .on('error', error => {
        if (stream.truncated)
          // delete the truncated file
          fs.unlinkSync(path);
        reject(error);
      })
      .pipe(fs.createWriteStream(path))
      .on('error', error => reject(error))
      .on('finish', () => resolve({ path }))
  );
}

来源:https://github.com/jaydenseric/apollo-upload-examples/blob/master/api/resolvers.mjs#L18


1
使用 stream 会产生 DeprecationWarning: File upload property ‘stream’ is deprecated. Use ‘createReadStream()’ instead. 的警告。解决方案是使用 { createReadStream, filename }createReadStream().on(...)。来源:https://github.com/apollographql/apollo-server/issues/2105#issuecomment-448424473 - Alexander Kachkaev
1
你好,我尝试了上面的代码,但我的文件总是返回这个错误信息:在文件上传流解析期间请求断开连接。 - kubido

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接