一个关于Nodejs的fs模块读取文件的疑惑
一个关于Nodejs的fs模块读取文件的疑惑
目的:读取output.txt文件中第10-14字节并打印.
存在ouput.txt 文件内容为 ABCDEFGHIJKLMNOP
示例程序为:
var fs=require(‘fs’); fs.open(__dirname+’/a.txt’,‘r’,function(err,fd){ if(err){throw err;} var buffer=new Buffer(5); var readBytes=0;
(function readIt(){
fs.read(fd,buffer,readBytes,buffer.length-readBytes,10+readBytes,function(err,bytesRead){
if(err){throw err;}
readBytes+=bytesRead;
if(readBytes===buffer.length){
console.log(buffer);
}else{
readIt();
}
});
})();
});
上代码运行正确,但请教各位,代码中 readBytes+=bytesRead; 语句,以及下面的if循环到底起到了什么作用,是否可以给分析下,谢谢.
这不是一次性读取文件内容的,每次readIt()
只读取了指定范围的内容,readBytes+=bytesRead
是累计计算读取的内容大小,if else
是判断是否读取完了
当然可以。让我们来分析一下你提供的代码,并解释 readBytes += bytesRead;
和 if (readBytes === buffer.length)
这两行代码的作用。
目标
读取 output.txt
文件中第10到14个字节,并打印出来。
示例代码
var fs = require('fs');
// 打开文件
fs.open(__dirname + '/output.txt', 'r', function(err, fd) {
if (err) { throw err; }
// 创建缓冲区,大小为5字节
var buffer = new Uint8Array(5);
var readBytes = 0;
// 递归函数用于读取文件
(function readIt() {
// 从文件中读取数据到缓冲区
fs.read(fd, buffer, readBytes, buffer.length - readBytes, 10 + readBytes, function(err, bytesRead) {
if (err) { throw err; }
// 更新已读字节数
readBytes += bytesRead;
// 如果已经读取了所有需要的数据,则打印结果
if (readBytes === buffer.length) {
console.log(buffer);
} else {
// 否则继续读取剩余的数据
readIt();
}
});
})();
});
代码解析
-
打开文件
fs.open(__dirname + '/output.txt', 'r', function(err, fd) { if (err) { throw err; }
使用
fs.open
打开文件,如果出错则抛出错误。 -
创建缓冲区
var buffer = new Uint8Array(5); var readBytes = 0;
创建一个5字节的缓冲区,并初始化已读字节数为0。
-
递归读取函数
(function readIt() { fs.read(fd, buffer, readBytes, buffer.length - readBytes, 10 + readBytes, function(err, bytesRead) { if (err) { throw err; } readBytes += bytesRead; if (readBytes === buffer.length) { console.log(buffer); } else { readIt(); } }); })();
fs.read
: 从文件描述符fd
中读取数据到buffer
,从当前位置开始读取buffer.length - readBytes
字节。readBytes += bytesRead;
: 更新已读字节数。if (readBytes === buffer.length)
: 如果已经读取了5个字节(即缓冲区的长度),则打印缓冲区内容。else { readIt(); }
: 否则继续调用readIt()
函数读取剩余的数据。
解释
readBytes += bytesRead;
更新当前已读字节数。if (readBytes === buffer.length)
判断是否已经读取完缓冲区的所有字节。如果是,则打印缓冲区内容;否则,继续递归读取。
这样可以确保每次读取的数据都被正确累加到缓冲区中,并且当缓冲区被填满时打印结果。
谢谢
在你的示例代码中,readBytes += bytesRead;
这一行的作用是追踪已经读取的字节数。而 if (readBytes === buffer.length)
这个条件判断则是用来检查是否已经读取了缓冲区中所有的字节。
具体来说,这段代码使用递归的方式去读取文件中的多个部分(每次读取5个字节),直到读取到目标位置(第10-14字节)。如果每次读取都恰好读满缓冲区的长度,则打印该缓冲区内容。
下面是简化后的代码,直接读取第10-14字节,并且打印出来:
const fs = require('fs');
const { createReadStream } = require('fs');
fs.open(__dirname + '/output.txt', 'r', (err, fd) => {
if (err) throw err;
const buffer = new Uint8Array(5); // 创建一个5字节大小的缓冲区
fs.read(fd, buffer, 0, buffer.length, 9, (err, bytesRead) => { // 从第10个字节开始读取
if (err) throw err;
// 将Buffer转换为字符串并打印
const result = buffer.slice(0, bytesRead).toString();
console.log(result); // 输出结果应为 "KLMNO"
fs.close(fd, () => {}); // 关闭文件描述符
});
});
在这个简化的版本中,我们直接从第10个字节开始读取5个字节,并将其转换为字符串后打印。这样可以避免递归调用,使代码更简洁易懂。