zoukankan      html  css  js  c++  java
  • 10.【转载】nodeJS中读写文件方法的区别

    原文地址:https://www.cnblogs.com/pp-cat/p/6504655.html

    导言:nodejs中所有与文件相关的操作都在fs模块中,而读写操作又是我们会经常用到的操作,nodejs的fs模块针对读操作为我们提供了readFile,read, createReadStream三个方法,针对写操作为我们提供了writeFile,write, createWriteStream三个方法,下面分析一下它们的区别:

    一、readFile和writeFile

    1、readFile方法是将要读取的文件内容完整读入缓存区,再从该缓存区中读取文件内容,具体操作如下:

    fs.readFile('./test.txt', 'utf8', function(err, data){
        console.log(data);  
    });

    与其对应的同步方法为:

    var data = fs.readFileSync('./test.txt', 'utf8');
    console.log(data);

    同步方法和异步方法的区别是:在使用同步方法执行的操作结束之前,不能执行后续代码的执行;而异步方法将操作结果作为回调函数的参数进行返回,方法调用之后,就可以立即执行后续的代码,读取完毕后会调用对应的回调函数。

    //异步方法
    fs.writeFile('./message.txt', '这是第一行',function(err){
        if(err) console.log('写文件操作失败');
        else console.log('写文件操作成功');
    });
    
    //同步方法
    fs.writeFileSync('./message.txt','这是第一行');

    以上的读写操作,Node.js将文件内容视为一个整体,为其分配缓存区并且一次性将文件内容读取到缓存区中,在这个期间,Node.js将不能执行任何其他处理。所以当读写大文件的时候,有可能造成缓存区“爆仓”。

    二、read和write

    1、read或readSync方法读取文件内容是不断地将文件中的一小块内容读入缓存区,最后从该缓存区中读取文件内容,具体操作如下:

    var fs = require('fs');
    fs.open('./message.txt','r',function(err,fd){
        var buf = new Buffer(225);
        //读取fd文件内容到buf缓存区
        fs.read(fd,buf,0,9,3,function(err,bytesRead,buffer){
            console.log(buf.slice(0,bytesRead).toString());
        }); 
        var buff = new Buffer(225);
        //位置设置为null会默认从文件当前位置读取
        fs.read(fd,buff,0,3,null,function(err,bytesRead,buffer){
            console.log(buff.slice(0,bytesRead).toString());
        });
    
        var buffer = new Buffer(225);
        //同步方法读取文件
        var bytesRead = fs.readFileSync(fd,buffer,0,9,3);
        console.log(bytesRead);
        console.log(buffer.slice(0,bytesRead).toString());
    });

    2、write或writeSync方法写入内容时,node.js执行以下过程:1将需要写入的数据写入到一个内存缓存区;2待缓存区写满后再将缓存区中的内容写入到文件中;3重复执行步骤1和步骤2,知道数据全部写入文件为止。具体操作如下:

    var fs = require('fs');
    var buf = new Buffer('我喜爱编程');
    fs.open('./mess.txt','w',function(err,fd){
        fs.write(fd,buf,3,9,0,function(err,written,buffer){
            fs.write(fd,buf,12,3,null,function(err,written,buffer){
                if(err) console.log('写文件操作失败');
                console.log('写文件操作成功');
            });
        });
        //同步写入
        fs.writeSync(fd,buf,3,9,0);
    });

    以上读写操作,node.js会将文件分成一块一块逐步操作,在读写文件过程中允许执行其他操作。

    但有的时候我们并不关心整个文件的内容,而只关注从文件中读取到的某些数据,以及读取到数据时需要执行的处理,这时我们可以使用文件流来处理。

    三、createReadStream和createWriteStream

    1、createReadStream方法创建一个将文件内容读取为流数据的ReadStream对象,方法如下所示:

    var fs = require('fs');
    var readStream = fs.createReadStream('./message.txt',{start:3,end:12});
    readStream.on('open',function(fd){
        console.log('开始读取文件');
    });
    readStream.on('data',function(data){
        console.log('读取到数据:');
        console.log(data);
    });
    readStream.on('end',function(){
        console.log('文件已全部读取完毕');
    });
    readStream.on('close',function(){
        console.log('文件被关闭');
    });
    readStream.on('error',function(err){
        console.log('读取文件失败');
    });

    2、createWriteStream方法创建一个将流数据写入文件中的WriteStream对象,方法如下所示:

    var fs = require('fs');
    var file = fs.createReadStream('./message.txt');
    var out = fs.createWriteStream('./anotherMessage.txt');
    file.on('data',function(data){
        out.write(data);
    });
    out.on('open',function(fd){
        console.log('需要被写入的文件已打开');
    });
    file.on('end',function(){
        //将操作系统缓存区中的数据全部写入文件
        out.end('再见',function(){
            console.log('文件全部写入完毕');
            console.log('共写入'+out.bytesWritten+'数据');
        });
    });

    以上方法可以对读写文件的过程中进行监听,并定义相关的方法pause和resume暂停或恢复文件的读取操作,可以监听写入时缓存区数据是否已满或者是否已全部输出,如下所示:

    //监听writeStream对象的drain事件
    var fs = require('fs');
    var out = fs.createWriteStream('./test1.txt');
    for(var i=0;i<10000;i++){
        //返回true或false true代表缓存区已满
        var flag = out.write(i.toString());
        console.log(flag);
    }
    out.on('drain',function(){
        console.log('操作系统缓存区中的数据已全部输出');
        var out = fs.createWriteStream('./test2.txt');
        for(var i=0;i<10;i++){
            var flag = out.write(i.toString());
            console.log(flag);
        }
        out.on('drain',function(){
            console.log('操作系统缓存区中的数据已全部输出');
        });
    });

  • 相关阅读:
    SQLMAP注入教程-11种常见SQLMAP使用方法详解
    VS2012/2013/2015/Visual Studio 2017 关闭单击文件进行预览的功能
    解决 IIS 反向代理ARR URLREWRITE 设置后,不能跨域跳转 return Redirect 问题
    Spring Data JPA one to one 共享主键关联
    JHipster 问题集中
    Spring Data JPA 定义超类
    Spring Data JPA查询关联数据
    maven命名
    maven仓库
    Jackson读取列表
  • 原文地址:https://www.cnblogs.com/Nick-Hu/p/10868168.html
Copyright © 2011-2022 走看看