我想从文件读取字节,这里是示例代码:
var fs = require('fs');
var stream= fs.createReadStream('./lib');
console.log(stream.read(10));
返回null。
我认为这是因为read()
方法直接从内部缓冲区获取数据。如果缓冲区没有足够的数据,则返回null
。 read()
方法是同步调用,没有传递回调,因此设计是有意义的。
但是,我不知道内部缓冲区何时可以拥有足够的数据,以便我的read()
调用可以返回数据,因为它现在处于暂停模式?
UPDATE1:
事件readable
是开始使用的好方法。但是,如果我想读取一个大文件,并且读取计数> 65536
,null将返回。
var fs = require('fs');
var stream = fs.createReadStream('./lib');
stream.on('readable', function () {
var buffer = stream.read(65537);
console.log(buffer.length);
});
我想要的是stream.read()总能将数据返回到EOF。
答案 0 :(得分:3)
在尝试阅读前等待readable
事件触发:
var fs = require('fs');
var stream= fs.createReadStream('./lib');
stream.on('readable', function () {
var buffer = stream.read(10);
if (buffer) {
console.log(buffer.toString());
}
});
答案 1 :(得分:3)
根据官方document:
内部缓冲区耗尽后,将触发“可读”事件 当有更多数据可用时再次。
我可以使用async / await,这样只要不在EOF,readable.read()就可以始终返回数据。
let rs = fs.createReadStream('./resources/1.gif');
async function readable(): Promise<{}> {
return new Promise(r => rs.on('readable', r));
}
async function readBytes(num: number = 0): Promise<Buffer> {
let buf = rs.read(num);
if (buf) {
return new Promise<Buffer>(r => r(buf));
}
else {
return new Promise<Buffer>(r => {
this.readable().then(() => {
this.readBytes(num).then(b => r(b));
});
});
}
}
async function main() {
console.log('begin');
console.log((await readBytes(10)).length);
console.log((await readBytes(65535)).length);
console.log((await readBytes(100000)).length);
console.log((await readBytes(10)).length);
console.log('end');
}
main();
输出:
begin
10
65535
100000
10
end
答案 2 :(得分:1)
如果我可以引用文档中的内容:https://nodejs.org/api/stream.html#stream_readable_read_size
const stream = fs.createReadStream('./lib');
stream.on('readable', () => {
let chunk;
while (null !== (chunk = stream.read())) {
console.log(`Received ${chunk.length} bytes of data.`);
}
});
答案 3 :(得分:0)
Streams以块的形式读取数据以进行处理。如果您只想获取文件的全部内容,则应使用fs.readFile()
。
fs.readFile(FILENAME, (err, data) => {
console.log(Buffer.isBuffer(data));
console.log(data.length);
})
另一方面,只要有适合您的数据,流就会发出data
事件。默认情况下,此流的highWaterMark
为64K。
var stream = fs.createReadStream(FILENAME);
var results = []
stream.on('data', function (chunk) {
// For text files chunk is string
// for binary files chunk is an instance of Buffer
// do something with this chunk...
results.push(`Chunk ${results.length} OK`)
});
stream.on('end', function() {
console.log(results);
})