我正在嘗試使用流讀取檔案。該檔案是一種自定義檔案格式,具有一定數量的部分,每個部分為 66 位元組。我必須根據給定的 32 個位元組檢查前 32 個位元組的值,如果它們匹配,則回傳剩余的 34 個位元組。目前我正在做以下事情
const fs = require('fs')
/**
* @param {string} known
*/
function check(known) {
let stream = fs.createReadStream('path/to/file', {highWaterMark: 66});
let out = '';
stream.on('data', (chunk) => {
let temp = '';
for (let i = 0; i < 32; i ) {
temp = String.fromCharCode(chunk.at(i));
}
if (temp === known) {
for (let i = 32; i < 66; i ) {
out = String.fromCharCode(chunk.at(i));
}
}
});
return out;
}
但是(通過檢查console.log)我知道函式在“完成”之后stream.on運行,因此無論是否找到給定的字串,回傳的值都將始終相同。怎么修?提前致謝 check
uj5u.com熱心網友回復:
流是非阻塞和異步的。check()在您的函式回傳后,他們會在未來某個時間呼叫他們的事件處理程式。他們就是這樣作業的。
因此,您不能直接從函式回傳結果,因為函式在結果已知之前回傳。相反,您必須使用異步機制回傳結果,例如事件、回呼或 Promise(在這種情況下我更喜歡 Promise)。有關回傳異步檢索值的更多詳細資訊,請參閱如何從異步呼叫回傳回應。
但是,使用流來讀取以 66 位元組塊為結構的檔案是撰寫此代碼的困難方法,因為data塊將是隨機大小的,并且不能保證與您的 66 位元組塊對齊。使用const fileHandle = await fs.promises.open(...)和fileHandle.read(...)從檔案開頭讀取 66 位元組塊,檢查要檢查的 32 位元組,然后使用承諾將剩余的 34 位元組通信回來會更簡單。
這是一種使用以下方式撰寫它的方法handle.read():
const fsp = require('fs').promises;
async function check(known) {
const kReadLen = 66;
const kHeaderLen = 32;
let handle = await fsp.open('path/to/file');
try {
let buffer = Buffer.alloc(kReadLen, 0);
let { bytesRead } = await handle.read(buffer, 0, kReadLen, 0);
if (bytesRead !== readLen) {
throw new Error("Insufficient data in the file");
}
const headerStr = buffer.toString('utf8', 0, kHeaderLen);
if (headerStr === known) {
return buffer.toString('utf8', kHeaderLen, kReadLen);
} else {
return "";
}
} finally {
handle.close();
}
}
樣品用法:
check(testKnown).then(result => {
console.log(result);
}).catch(err => {
console.log(err);
})
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/439983.html
標籤:javascript 节点.js
上一篇:檢查一個鍵是否在gun.js中
