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

溫馨提示×

溫馨提示×

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

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

使用Node.js怎么從字符串生成文件流

發布時間:2021-04-19 17:59:34 來源:億速云 閱讀:563 作者:Leah 欄目:web開發

使用Node.js怎么從字符串生成文件流?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

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);
});

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

const FormData = require('form-data');

const filename = 'my-file.txt';
const content = 'balalalalala...變身';

const formData = new FormData();
// 1.先將字符串轉換成Buffer
const 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

重新實現文件流

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

// 從文件中讀取一個chunk
fs.read(this.fd, pool, pool.used, toRead, this.pos, (er, bytesRead) => {
 /* ... */
});

// 換成
this._fakeReadFile(this.fd, pool, pool.used, toRead, this.pos, (bytesRead) => {
 /* ... */
});

// 從輸入字符串對應的Buffer中copy出一個chunk
ReadStream.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);
});

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

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

AI

罗平县| 霍林郭勒市| 抚宁县| 扬中市| 德惠市| 江口县| 荃湾区| 大石桥市| 凌海市| 志丹县| 元阳县| 兴业县| 新安县| 庄浪县| 台州市| 仁怀市| 古交市| 青阳县| 镇远县| 台东县| 潮安县| 蕲春县| 嘉峪关市| 邳州市| 神木县| 尖扎县| 惠水县| 安仁县| 栖霞市| 黎城县| 北川| 子长县| 平原县| 辽阳市| 贡觉县| 青岛市| 常山县| 南溪县| 台安县| 通山县| 木兰县|