亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

Node.js從字符串生成文件流的實現方法

2024-05-06 16:54:19
字體:
來源:轉載
供稿:網友

一.背景

在文件相關的數據加工等場景下,經常面臨生成的物理文件應該如何處理的問題,比如:

生成的文件放到哪里,路徑存在不存在?

臨時文件何時清理,如何解決命名沖突,防止覆蓋?

并發場景下的讀寫順序如何保證?

……

對于讀寫物理文件帶來的這些問題,最好的解決辦法就是 不寫文件 。然而,一些場景下想要不寫文件可不那么容易,比如文件上傳

二.問題

文件上傳一般通過表單提交來實現,例如:

var FormData = require('form-data');var fs = require('fs');var form = new FormData();form.append('my_file', fs.createReadStream('/foo/bar.jpg'));form.submit('example.org/upload', function(err, res) { console.log(res.statusCode);});

(摘自 Form-Data )

不想寫物理文件的話,可以這樣做:

const FormData = require('form-data');const filename = 'my-file.txt';const content = 'balalalalala...變身';const formData = new FormData();// 1.先將字符串轉換成Bufferconst fileContent = Buffer.from(content);// 2.補上文件meta信息formData.append('file', fileContent, { filename, contentType: 'text/plain', knownLength: fileContent.byteLength});

也就是說,文件流除了能夠提供數據外,還具有一些 meta 信息,如文件名、文件路徑等 ,而這些信息是普通 Stream 所不具備的。那么,有沒有辦法憑空創建一個“真正的”文件流?

三.思路

要想創建出“真正的”文件流,至少有正反 2 種思路:

給普通流添上文件相關的 meta 信息

先拿到一個真正的文件流,再改掉其數據和 meta 信息

顯然,前者更靈活一些,并且實現上能夠做到完全不依賴文件

文件流的生產過程

沿著憑空創造的思路,探究 fs.createReadStream API 的 內部實現 之后發現,生產文件流的關鍵過程如下:

function ReadStream(path, options) { // 1.打開path指定的文件 if (typeof this.fd !== 'number')  this.open();}ReadStream.prototype.open = function() { fs.open(this.path, this.flags, this.mode, (er, fd) => {  // 2.拿到文件描述符并持有  this.fd = fd;  this.emit('open', fd);  this.emit('ready');  // 3.開始流式讀取數據  // read來自父類Readable,主要調用內部方法_read  // ref: https://github.com/nodejs/node/blob/v10.16.3/lib/_stream_readable.js#L390  this.read(); });};ReadStream.prototype._read = function(n) { // 4.從文件中讀取一個chunk fs.read(this.fd, pool, pool.used, toRead, this.pos, (er, bytesRead) => {  let b = null;  if (bytesRead > 0) {   this.bytesRead += bytesRead;   b = thisPool.slice(start, start + bytesRead);  }  // 5.(通過觸發data事件)吐出一個chunk,如果還有數據,process.nextTick再次this.read,直至this.push(null)觸發'end'事件  // ref: https://github.com/nodejs/node/blob/v10.16.3/lib/_stream_readable.js#L207  this.push(b); });};

P.S.其中第 5 步相對復雜, this.push(buffer) 既能觸發下一個 chunk 的讀取( this.read() ),也能在數據讀完之后(通過 this.push(null) )觸發 'end' 事件,具體見 node/lib/_stream_readable.js

重新實現文件流

既然已經摸清了文件流的生產過程,下一步自然是 替換掉所有文件操作,直至文件流的實現完全不依賴文件 ,例如:

// 從文件中讀取一個chunkfs.read(this.fd, pool, pool.used, toRead, this.pos, (er, bytesRead) => { /* ... */});// 換成this._fakeReadFile(this.fd, pool, pool.used, toRead, this.pos, (bytesRead) => { /* ... */});// 從輸入字符串對應的Buffer中copy出一個chunkReadStream.prototype._fakeReadFile = function(_, buffer, offset, length, position, cb) { position = position || this.input._position; // fake read file async setTimeout(() => {  let bytesRead = 0;  if (position < this.input.byteLength) {   bytesRead = this.input.copy(buffer, offset, position, position + length - 1);   this.input._position += bytesRead;  }  cb(bytesRead); }, 0);}

即從中剔除文件操作,用基于字符串的操作去替代它們

四.解決方案

如此這般,就有了 ayqy/string-to-file-stream ,用來憑空創建文件流:

string2fileStream('string-content') === fs.createReadStream(/* path to a text file with content 'string-content' */)`

例如:

const string2fileStream = require('string-to-file-stream');const input = 'Oh, my great data!';const s = string2fileStream(input);s.on('data', (chunk) => { assert.equal(chunk.toString(), input);});生成的流同樣能夠具有文件 meta 信息:const string2fileStream = require('string-to-file-stream');const formData = new FormData();formData.append('file', string2fileStream('my-string-data', { path: './abc.txt' }));form.submit('example.org/upload', function(err, res) { console.log(res.statusCode);});

足夠以假亂真

參考資料

fs.createReadStream(path[, options])

fs/streams.js

_stream_readable.js

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品第10页| 欧美大片在线影院| 精品视频在线播放色网色视频| 成人综合网网址| 国产成人鲁鲁免费视频a| 久国内精品在线| 伊人青青综合网站| 中文字幕在线视频日韩| 国产成人自拍视频在线观看| 欧美激情精品久久久久久大尺度| 欧美猛交ⅹxxx乱大交视频| 成人中文字幕在线观看| 久久伊人91精品综合网站| 国内成人精品一区| 亚洲大胆人体在线| 日本精品中文字幕| 欧美在线免费视频| 久久天天躁狠狠躁夜夜躁| 国内精品久久久久久| 国产精品一区久久久| 国产精品丝袜白浆摸在线| 91精品国产免费久久久久久| 成人性生交大片免费看视频直播| 日本三级久久久| 韩日欧美一区二区| 91精品久久久久久久久久| 亚洲国产精品小视频| 精品国产精品三级精品av网址| 日韩欧美极品在线观看| 国产精品人人做人人爽| 怡红院精品视频| 亚洲色图色老头| 不卡在线观看电视剧完整版| 国产精品高潮呻吟视频| 国产精品午夜视频| 亚洲国产毛片完整版| 久久影院中文字幕| 日韩有码在线观看| 久久精品国产欧美亚洲人人爽| 国产一区二区在线免费视频| 欧美在线免费看| 国产美女高潮久久白浆| 亚洲高清福利视频| 久久黄色av网站| 久久成人国产精品| 九九热这里只有精品免费看| 亚洲成在人线av| 45www国产精品网站| 久久精品国产亚洲精品| 欧美性猛交xxxx乱大交蜜桃| 黑人巨大精品欧美一区二区三区| 亚洲在线视频观看| 亚洲综合中文字幕68页| 亚洲免费av片| 亚洲精选一区二区| 亚洲国产精品久久久久秋霞不卡| 成人av.网址在线网站| 精品欧美激情精品一区| 91久久综合亚洲鲁鲁五月天| 国产精品国产三级国产专播精品人| 欧美日本亚洲视频| 国产精品91在线观看| 69久久夜色精品国产69乱青草| 日本久久亚洲电影| 日本精品中文字幕| 国产狼人综合免费视频| 成人黄色免费看| 中文字幕日韩在线播放| 欧美成人午夜激情| 久久成人人人人精品欧| 久久九九热免费视频| 91沈先生作品| 日韩www在线| 欧美美最猛性xxxxxx| 国产网站欧美日韩免费精品在线观看| 日韩美女视频中文字幕| 亚洲欧美自拍一区| 日韩视频免费在线观看| 欧美高清在线播放| 欧美国产日韩xxxxx| 国产亚洲激情视频在线| 国产视频丨精品|在线观看| 91精品久久久久久久久久久久久| 大伊人狠狠躁夜夜躁av一区| 日韩麻豆第一页| 精品久久中文字幕| 亚洲性线免费观看视频成熟| 在线观看国产精品日韩av| 国产精品视频免费在线| 国产精品视频yy9099| 69**夜色精品国产69乱| 狠狠躁夜夜躁久久躁别揉| 国模gogo一区二区大胆私拍| 欧美日韩一二三四五区| 国产精品aaaa| 538国产精品一区二区免费视频| 一本大道久久加勒比香蕉| 色综合亚洲精品激情狠狠| 最近2019免费中文字幕视频三| 欧美做爰性生交视频| 日韩成人在线视频网站| 国产福利精品在线| 97久久超碰福利国产精品…| 中文字幕在线精品| 亚洲男人天堂2023| 久久亚洲国产成人| 久久男人的天堂| 亚洲最大av在线| 日韩精品在线免费播放| 亚洲直播在线一区| 欧美激情喷水视频| 欧美视频免费在线观看| 欧美亚洲国产成人精品| 久久精品国产久精国产一老狼| 91国产精品视频在线| 热门国产精品亚洲第一区在线| 久久综合国产精品台湾中文娱乐网| 韩剧1988免费观看全集| 久久久99久久精品女同性| 欧美精品videosex极品1| www.亚洲天堂| 日韩精品亚洲元码| 久久影院中文字幕| 91香蕉嫩草神马影院在线观看| 国产一区二区三区四区福利| 一本一本久久a久久精品综合小说| 久99九色视频在线观看| 色婷婷av一区二区三区久久| 国产精品久久久久久婷婷天堂| 国产精品高潮在线| 热re91久久精品国99热蜜臀| 中文字幕久热精品在线视频| 国产日本欧美在线观看| 欧美另类极品videosbest最新版本| 精品久久久久国产| 国产亚洲一区精品| 神马久久久久久| 久久国产精品久久久久久久久久| 日韩中文字幕在线观看| 高清欧美性猛交xxxx| 欧美理论电影在线播放| 日本不卡高字幕在线2019| 欧美日韩午夜视频在线观看| 精品久久久久久久久久久久久久| 国产精品视频播放| 91在线视频一区| 欧美xxxx做受欧美| 美乳少妇欧美精品| 在线视频免费一区二区| 9.1国产丝袜在线观看| 91免费人成网站在线观看18| 自拍偷拍亚洲欧美| 91老司机精品视频| 91最新国产视频| 韩日精品中文字幕| 亚洲精品大尺度| 亚洲国产精品一区二区三区| 成人精品久久一区二区三区| 亚洲欧美综合另类中字| 国产精品电影一区| 亚洲综合社区网| 国产欧美 在线欧美| 久久夜精品香蕉| 亚洲欧美另类自拍|