NodeJS:获取文件,而不是缓冲区

Posted

技术标签:

【中文标题】NodeJS:获取文件,而不是缓冲区【英文标题】:NodeJS: Get File, not Buffer 【发布时间】:2019-04-28 03:07:03 【问题描述】:

我已经在我的apollo GraphQL 服务器上设置了一个突变,使用graphql-upload (或apollo-upload-server 来接收来自客户端的文件,现在我正在尝试编写一个测试这个突变,但我不确定如何将实际文件附加到我的模拟请求中。

在我的客户端我有一个input type="file",在上传事件中我提取文件

async upload(event) 
  const files = event.target.files || event.dataTransfer.files;
  const file = files[0]; // type of file is File
  await apollo.mutate(
    mutation: gql`
      mutation UploadFile($file: Upload) 
        uploadFile(file: $file)
      
    `,
    variables:  file ,
  )

到目前为止一切都很好。但我也想在我的服务器上写一个测试用例。

这是我的问题

在我的服务器上,我想模仿客户端上传文件。但我找不到如何从 NodeJS 中访问实际文件。

我试过了:

const file = fs.readFileSync('path/to/test-file.csv');

但是fs 返回一个Buffer,而不是File 类型,它还包含元数据,例如mimetypenamelastModified 属性。

如何获得实际的 File object 而不是 Buffer

谢谢!

【问题讨论】:

指定编码例如:fs.readFileSync('path/to/test-file.csv', 'utf8'); 我知道它将缓冲区作为格式化字符串返回,但这不是我想要的。据我所知,缓冲区不包含元数据,只包含文件的内容,它是我感兴趣的元数据,表示为File 类型的对象。 【参考方案1】:

简单:

const file = fs.readFileSync('path/to/test-files.csv').toString();

希望对你有帮助:-)

【讨论】:

我知道toString() 将缓冲区作为格式化字符串返回,但这不是我想要的。据我所知,缓冲区不包含元数据,只包含文件的内容,这是我感兴趣的元数据。 您可以使用 fs.stat,它会为您提供上次修改的文件名,... 请参阅 nodejs.org/api/fs.html#fs_class_fs_stats。对于 mime 类型,我不知道你是如何做到的……我猜 fs.stat 足以构建一个进度条 谢谢,如果没有更好的选择,我会研究一下。我见过可以获取 mimetype 的库,但如果无法直接获取 File 对象,我会感到惊讶。【参考方案2】:

您可以将编码设置为 utf-8。

fs.readFile(path.resolve(path),  encoding: 'utf-8', flag: 'r' , (error, data) => 

)

【讨论】:

不,谢谢,我知道它将缓冲区作为格式化字符串返回,但这不是我想要的。据我所知,缓冲区不包含元数据,只包含文件的内容,它是我感兴趣的元数据,表示为 File 类型的对象。【参考方案3】:

Node.js 中没有 File 类。在您假设该平台存在的某个类的对象中,没有任何东西可以复合 MIME 类型、文件内容和文件名。您将不得不使用不同的方法来获取所需的所有信息:

    fs.readFileSync 可以从文件描述符或文件路径中获取文件的内容fs.lstatSyncfs.fstatSync [同步,与 readFileSync 一样] 为您提供一些您想要的属性,尤其是文件的“最后修改时间戳”。

获取文件的 MIME 类型没有明确的公认方法 - 即使某些类型数据的某些 MIME 类型是标准化的,但通常会应用对内容的启发式分析来确定文件的 MIME 类型。例如,对于同样是有效 XML 文件的 SVG 文件(通常为 *.svg),您需要确保该文件可解析为 XML,以确定根“svg”元素属于SVG 命名空间通过将声明的命名空间 URI 与已知的 SVG 元素命名空间进行比较,然后您可以断言该文件是 image/svg+xml MIME 类型。这种方法——对实际文件内容的一些分析——将适用于任何确定 MIME 类型的情况,如果你想确定的话。

现在,大多数 Web 服务器只使用文件的扩展名作为 MIME 类型映射的键——例如,所有*.gif 文件都被称为image/gif MIME 类型,即使有垃圾或纯文本在他们之中。这是因为 Web 服务器和客户端通常都不需要启发式分析——如果假定为 GIF 的文件实际上是垃圾,客户端将中止渲染或渲染垃圾,但确保文件内容有效的责任在于无论谁拥有该文件,而不是 Web 服务器,而后者并不关心内容,它只 提供 内容,通常解析它并不是它的责任(不是“资产”文件)。然而,真正的原因当然是性能——考虑到启发式分析通常比仅根据文件扩展名确定 MIME 类型的成本更高,因此首选后一种方法。

【讨论】:

以上是关于NodeJS:获取文件,而不是缓冲区的主要内容,如果未能解决你的问题,请参考以下文章

NodeJS 将二进制缓冲区写入文件

nodejs 怎么获取文件大小

Nodejs:从视频缓冲区(不是文件路径)生成缩略图

nodejs怎样获取一个上传文件的MD5码?

如何从 Nodejs Mysql 获取 JSON 类型作为 JSON 而不是 String

nodejs 热更新