千家信息网

怎么实现图片上传写入磁盘的接口

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,本篇内容主要讲解"怎么实现图片上传写入磁盘的接口",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"怎么实现图片上传写入磁盘的接口"吧!一:开启 Node.js
千家信息网最后更新 2026年11月01日怎么实现图片上传写入磁盘的接口

本篇内容主要讲解"怎么实现图片上传写入磁盘的接口",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"怎么实现图片上传写入磁盘的接口"吧!

一:开启 Node.js 服务

开启一个 Node.js 服务,指定路由 /upload/image 收到请求后调用 uploadImageHandler 方法,传入 Request 对象。

const http = require('http'); const formidable = require('formidable'); const fs = require('fs'); const fsPromises = fs.promises; const path = require('path'); const PORT = process.env.PORT || 3000; const server = http.createServer(async (req, res) => {   if (req.url === '/upload/image' &&  req.method.toLocaleLowerCase() === 'post') {     uploadImageHandler(req, res);   } else {    res.setHeader('statusCode', 404);    res.end('Not found!')   } }); server.listen(PORT, () => {   console.log(`server is listening at ${server.address().port}`); });

二:处理图片对象

formidable 是一个用来处理上传文件、图片等数据的 NPM 模块,form.parse 是一个 callback 转化为 Promise 便于处理。

Tips:拼接路径时使用 path 模块的 join 方法,它会将我们传入的多个路径参数拼接起来,因为 Linux、Windows 等不同的系统使用的符号是不同的,该方法会根据系统自行转换处理。

const uploadImageHandler = async (req, res) => {   const form = new formidable.IncomingForm({ multiples: true });     form.encoding = 'utf-8';     form.maxFieldsSize = 1024 * 5;     form.keepExtensions = true;    try {     const { file } = await new Promise((resolve, reject) => {         form.parse(req, (err, fields, file) => {           if (err) {             return reject(err);           }           return resolve({ fields, file });         });       });     const { name: filename, path: sourcePath } = file.img;     const destPath = path.join(__dirname, filename);     console.log(`sourcePath: ${sourcePath}. destPath: ${destPath}`);     await mv(sourcePath, destPath);     console.log(`File ${filename} write success.`);     res.writeHead(200, { 'Content-Type': 'application/json' });     res.end(JSON.stringify({ code: 'SUCCESS', message: `Upload success.`}));   } catch (err) {     console.error(`Move file failed with message: ${err.message}`);     res.writeHead(200, { 'Content-Type': 'application/json' });     res.end(JSON.stringify({ code: 'ERROR', message: `${err.message}`}));   } }

三:实现 mv 方法

fs.rename 重命名文件

将上传的图片写入本地目标路径一种简单的方法是使用 fs 模块的 rename(sourcePath, destPath) 方法,该方法会异步的对 sourcePath 文件做重命名操作,使用如下所示:

const mv = async (sourcePath, destPath) => {  return fsPromises.rename(sourcePath, destPath); };

cross-device link not permitted

在使用 fs.rename() 时还要注意 cross-device link not permitted 错误,参考 rename(2) — Linux manual page:

**EXDEV **oldpath and newpath are not on the same mounted filesystem. (Linux permits a filesystem to be mounted at multiple points, but rename() does not work across different mount points, even if the same filesystem is mounted on both.)

oldPath 和 newPath 不在同一挂载的文件系统上。(Linux 允许一个文件系统挂载到多个点,但是 rename() 无法跨不同的挂载点进行工作,即使相同的文件系统被挂载在两个挂载点上。)

在 Windows 系统同样会遇到此问题,参考 http://errorco.de/win32/winerror-h/error_not_same_device/0x80070011/

winerror.h 0x80070011 #define ERROR_NOT_SAME_DEVICE The system cannot move the file to a different disk drive.(系统无法移动文件到不同的磁盘驱动器。)

此处在 Windows 做下复现,因为在使用 formidable 上传文件时默认的目录是操作系统的默认目录 os.tmpdir(),在我的电脑上对应的是 C 盘下,当我使用 fs.rename() 将其重名为 F 盘时,就出现了以下报错:

C:\Users\ADMINI~1\AppData\Local\Temp\upload_3cc33e9403930347b89ea47e4045b940 F:\study\test\202366 [Error: EXDEV: cross-device link not permitted, rename 'C:\Users\ADMINI~1\AppData\Local\Temp\upload_3cc33e9403930347b89ea47e4045b940' -> 'F:\study\test\202366'] {   errno: -4037,   code: 'EXDEV',   syscall: 'rename',   path: 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\upload_3cc33e9403930347b89ea47e4045b940',   dest: 'F:\\study\\test\\202366' }

设置源路径与目标路径在同一磁盘分区

设置上传文件中间件的临时路径为最终写入文件的磁盘分区,例如我们在 Windows 测试时将图片保存在 F 盘下,所以设置 formidable 的 form 对象的 uploadDir 属性为 F 盘,如下所示:

const form = new formidable.IncomingForm({ multiples: true });   form.uploadDir = 'F:\\' form.parse(req, (err, fields, file) => {     ... });

这种方式有一定局限性,如果写入的位置位于不同的磁盘空间该怎么办呢?

可以看下下面的这种方式。

读取-写入-删除临时文件

一种可行的办法是读取临时文件写入到新的位置,最后在删除临时文件。所以下述代码创建了可读流与可写流对象,使用 pipe 以管道的方式将数据写入新的位置,最后调用 fs 模块的 unlink 方法删除临时文件。

const mv = async (sourcePath, destPath) => {   try {     await fsPromises.rename(sourcePath, destPath);   } catch (error) {     if (error.code === 'EXDEV') {       const readStream = fs.createReadStream(sourcePath);         const writeStream = fs.createWriteStream(destPath);       return new Promise((resolve, reject) => {         readStream.pipe(writeStream);         readStream.on('end', onClose);         readStream.on('error', onError);         async function onClose() {           await fsPromises.unlink(sourcePath);           resolve();         }         function onError(err) {           console.error(`File write failed with message: ${err.message}`);             writeStream.close();           reject(err)         }       })     }      throw error;   } }

四:测试

方式一:终端调用

curl --location --request POST 'localhost:3000/upload/image' \ --form 'img=@/Users/Downloads/五月君.jpeg'

方式二:POSTMAN 调用

到此,相信大家对"怎么实现图片上传写入磁盘的接口"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

文件 方法 系统 图片 磁盘 路径 不同 方式 对象 模块 处理 接口 位置 内容 多个 数据 目录 目标 参考 学习 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 科技互联网 广州为想互联网科技有限公司 上海卓越科技互联网 互联网科技深圳 涨乐互联网科技 新华互联网科技学院 天津摩尔互联网科技 上海致骋互联网科技 互联网公司会议桌创意科技软装饰 北京华百购互联网科技有限公司 深圳市罗太互联网科技有限公司 互联网科技的全部知识 互联网在线教育科技创业 华中科技大学互联网的牛人 美国互联网科技实力 城市宝互联网科技有限公司 21世纪互联网科技成就 上海互联网科技公司ppt 山东大美朱楼互联网科技有限公司 上海互联网科技园景观 广州互联网络科技有限公司 北京禾田雨橡互联网科技 苏州铭阳互联网科技有限公司 亳州好赞互联网科技有限公司 有人说阿里系是互联网科技企业 互联网硬科技公司 互联网科技手机排行榜 深圳互联网科技园地址 互联网科技大佬云集 北京瑞云互联网科技有限公司
0