中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么實現圖片上傳寫入磁盤的接口

發布時間:2021-10-20 16:54:14 來源:億速云 閱讀:128 作者:iii 欄目:web開發

本篇內容主要講解“怎么實現圖片上傳寫入磁盤的接口”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么實現圖片上傳寫入磁盤的接口”吧!

 

一:開啟 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 調用

怎么實現圖片上傳寫入磁盤的接口

到此,相信大家對“怎么實現圖片上傳寫入磁盤的接口”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

布拖县| 南昌市| 莱西市| 维西| 繁峙县| 仪征市| 封开县| 平南县| 海口市| 玉环县| 岱山县| 巩留县| 凌云县| 治县。| 仁化县| 获嘉县| 女性| 驻马店市| 墨江| 安庆市| 博客| 即墨市| 桐梓县| 皋兰县| 安化县| 新兴县| 金阳县| 凤山县| 涟源市| 六安市| 乌拉特后旗| 潜江市| 台山市| 石首市| 齐齐哈尔市| 钟山县| 宜春市| 新乐市| 乌拉特前旗| 曲沃县| 芦山县|