分享更有价值
被信任是一种快乐

Nodejs如何进行大文件读写

文章页正文上

这篇文章主要介绍了Nodejs如何进行大文件读写的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Nodejs如何进行大文件读写文章都会有所收获,下面我们一起来看看吧。常规的,如果我们要读取一个比较小的文件,可以直接通过:

constfs=require('fs')
letdata=fs.readFileSync("./test.png")
console.log(data,123)
//输出data=

一般而言,同步的方法不是很推荐,因为js/nodejs是单线程的,同步的方法会阻塞主线程。最新版的node直接提供了fs.promise,可以结合async/await直接使用:

constfs=require('fs')
constreadFileSync=async()=>{
letdata=awaitfs.promises.readFile("./test.png")
console.log(data,123)
}
readFileSync()
//输出data=

这里通过异步的方法调用不会阻塞主线程,多个文件读取的IO也可以并行进行等。常规的文件读写,我们会把文件一次性的读取到内存中,这种方法时间效率和内存效率都很低,时间效率低是指必须要一次性读取完毕后才能执行后续才做,内存效率低是指必须把这个文件都一次性读取放入内存中,很占用内存。因此这种情况下,我们一般使用St免费云主机、域名ream来进行文件的读取:

constfs=require('fs')
constreadFileTest=()=>{
vardata=''
varrs=fs.createReadStream('./test.png');
rs.on('data',function(chunk){
data+=chunk;
console.log(chunk)
});
rs.on('end',function(){
console.log(data);
});
rs.on('error',function(err){
console.log(err.stack);
});
}
readFileTest()
//data=

通过Steam来进行文件读写,可以提高内存效率和时间效率。内存效率:在处理数据之前,不需要在内存中加载大量(或整个)数据时间效率:一旦有了数据,就可以开始处理,这大大减少开始处理数据的时间,而不必等到整个数据加载完毕再进行处理。Stream的文件还支持第二种写法:

constfs=require('fs')
constreadFileTest=()=>{
vardata=''
varchunk;
varrs=fs.createReadStream('./test.png');
rs.on('readable',function(){
while((chunk=rs.read())!=null){
data+=chunk;
}});
rs.on('end',function(){
console.log(data)
});
};
readFileTest()

在读取大文件时,会有读取文件大小的限制,比如我们现在在读取一个2.5G的视频文件:

constfs=require('fs')
constreadFileTest=async()=>{
letdata=awaitfs.promises.readFile("./video.mp4")
console.log(data)
}
readFileTest()

执行上述的代码会报错:RangeError [ERR_FS_FILE_TOO_LARGE]: File size (2246121911) is greater than 2 GB我们可能会想到,通过设置option,NODE_OPTIONS=’–max-old-space-size=5000’,此时5000M>2.5G,但是报错还是没有消失,也就是说通过Options无法改变node读取文件的大小限制。上述是常规的方式读取大文件,如果通过Steam的方式读取还会有文件大小的限制嘛? 比如:

constfs=require('fs')
constreadFileTest=()=>{
vardata=''
varrs=fs.createReadStream('./video.mp4');
rs.on('data',function(chunk){
data+=chunk;
});
rs.on('end',function(){
console.log(data);
});
rs.on('error',function(err){
console.log(err.stack);
});
}
readFileTest()

如上方式读取一个2.5G的文件不会有异常,不过要注意的是这边有一个报错:

data+=chunk;
^

RangeError:Invalidstringlength

如上方式读取一个2.5G的文件不会有异常,不过要注意的是这边有一个报错:此时是因为data的长度超过了最大限制,比如2048M等。因此在用Steam处理的时候,在对读取结果的保存时,要注意文件的大小,千万不能超过默认的Buffer的最大值。上述这种情况,我们不用data += chunk将数据全部保存在一个大的data中,我们可以边读取边处理。createReadStream在读取文件的过程中,其实也可以分段读取,这种分段读取的方法也可以做为大文件读取的备选项。特别是在并发读取的时候有一定的优点,可以提升文件读取和处理的速度。createReadStream接受第二个参数{start,end}。我们可以通过fs.promises.stat来获取文件的大小,然后确定分片,最后分片一次读取,比如:获取文件大小

constinfo=awaitfs.promises.stat(filepath)
constsize=info.size

登录后复制

登录后复制按照指定的SIZE分片(比如128M一个分片)

constSIZE=128*1024*1024
letsizeLen=Math.floor(size/SIZE)
lettotal=sizeLen+1;
for(leti=0;i

3.实现读取函数

constreadStremfunc=()=>{
constreadStream=fs.createReadStream(filepath,{start:start,end:end})
readStream.setEncoding('binary')
letdata=''
readStream.on('data',chunk=>{
data=data+chunk
})
readStream.end('data',()=>{
...
})
}

值得注意的是fs.createReadStream(filepath,{start,end}),start和end是前闭后闭的,比如fs.createReadSteam(filepath,{start:0,end:1023})读取的是[0,1023]一共1024个bit。前面将了大文件在nodejs中的读取,那么在浏览器端会读取大文件会有什么问题吗?浏览器在本地读取大文件时,之前有类似FileSaver、StreamSaver等方案,不过在浏览器本身添加了File的规范,使得浏览器本身就默认和优化了Stream的读取。我们不需要做额外的工作,相关的工作:github.com/whatwg/fs。不过不同的版本会有兼容性的问题,我们还是可以通过FileSaver等进行兼容。如果是在浏览器中获取静态资源大文件,一般情况下只需要通过range分配请求即可,一般的CDN加速域名,不管是阿里云还是腾讯云,对于分片请求都支持的很好,我们可以将资源通过cdn加速,然后在浏览器端直接请求cdn加速有的资源。分片获取cdn静态资源大文件的步骤为,首先通过head请求获取文件大小:

constgetHeaderInfo=async(url:string)=>{
constres:any=awaitaxios.head(url+`?${Math.random()}`);
returnres?.headers;
};
constheader=getHeaderInfo(source_url)
constsize=header['content-length']

我们可以从header中的content-length属性中,获取文件的大小。然后进行分片和分段,最后发起range请求:

constgetRangeInfo=async(url:string,start:number,end:number)=>{
constdata=awaitaxios({
method:'get',
url,
headers:{
range:`bytes=${start}-${end}`,
},
responseType:'blob',
});
returndata?.data;
};

在headers中指定 range: bytes=${start}-${end},就可以发起分片请求去获取分段资源,这里的start和end也是前闭后闭的。关于“Nodejs如何进行大文件读写”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“Nodejs如何进行大文件读写”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注云技术行业资讯频道。

相关推荐: 如何使用JQuery的turn.js库来实现翻书效果

这篇文章主要介绍“如何使用JQuery的turn.js库来实现翻书效果”,在日常操作中,相信很多人在如何使用JQuery的turn.js库来实现翻书效果问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何使用JQuery的turn…

文章页内容下
赞(0) 打赏
版权声明:本站采用知识共享、学习交流,不允许用于商业用途;文章由发布者自行承担一切责任,与本站无关。
文章页正文下
文章页评论上

云服务器、web空间可免费试用

宝塔面板主机、支持php,mysql等,SSL部署;安全高速企业专供99.999%稳定,另有高防主机、不限制内容等类型,具体可咨询QQ:360163164,Tel同微信:18905205712

主机选购导航云服务器试用

登录

找回密码

注册