node文件读写+node执行python文件

系统 2794 0

一、node文件读写

Node.js读取文件函数语法如下:

 

1. 异步读文件

fs.readFile(filename,[encoding],[callback(err,data)])

  • filename(必选),表示要读取的文件名。
  • encoding(可选),表示文件的字符编码。
  • callback 是回调函数,用于接收文件的内容。

示例:

            
              var fs=require('fs');

fs.readFile('./data/result.txt', 'utf-8', function (err, stdout) {
  if (err) {
    console.log('文件读取失败');
  } else {
    console.log('文件读取成功');
    res.render('index', {
      input: description,
      content: stdout,
    })
    console.log('stdout:', stdout);
    stdout = '';
  }
});
            
          

 

PS:read和readFile比较

read 是不断地将文件中的一小块内容读入缓存区,最后从该缓存区中读取文件内容,
而readFile 则是将文件一次性读取完毕,如果文件较大,则会出现"爆仓"。

 

2.异步写文件

fs.writeFile(filename,data,[options],callback)

  • filename:要写入的文件
  • data:写入文件的数据可以是字符串,可以是buffer
  • options:flag:对写入文件的操作默认为w,encoding:编码,mode:权限
  • callback:回调函数

 

以下介绍下常见的文件的操作 flag, 详细文件操作区别请看这篇文章

♥ flag: w -- 新建只写(以 w 方式打开,不能读出,w+ 可读写)

              a -- 附加写方式 (a:附加写方式打开,不可读;a+: 附加读写方式打开)

♥ 如果文件不存在会创建新文件的打开方式:a,a+,w,w+,而  r 和 U 要求文件必须存在

 

示例:

            
              // 引入fs
var fs = require("fs");

// 获取用户提交的内容
var description = req.body.description;

// 写入文件
fs.writeFile('./data/text.txt', description, {
  flag: 'w',
  encoding: 'utf-8',
  mode: '0666'
}, function (err) {
  if (err) {
    console.log("文件写入失败")
  } else {
    console.log("文件写入成功");
  }
});
            
          


3.同步读写文件

            
              var date = fs.readFileSync('log.txt','utf-8');

fs.writeFileSync('output.txt', JSON.stringify(obj, null, '\t'));
            
          

 

4.同步与异步读写的区别

♥ 同步会阻塞,阻塞时,代码不能做其它的事情,需要等待当前代码执行完毕, 而异步则无需等待当前代码执行完毕。

 

二、node执行python文件

 

1. child_process介绍

Node.js 是以单线程的模式运行的,但它使用的是事件驱动来处理并发。这样有助于我们在多核 cpu 的系统上创建多个子进程,并使用主进程和子进程之间实现通信,从而提高性能。

每个子进程总是带有三个流对象:child.stdin, child.stdout 和child.stderr。他们可能会共享父进程的 stdio 流,或者也可以是独立的被导流的流对象。

Node 提供了  child_process  模块来创建子进程。

 

2. 创建子进程方法

  • exec-child_process.exec         

使用子进程执行命令,缓存子进程的输出,并将子进程的输出以回调函数的形式返回。

示例:

            
              var child_process = require('child_process');

var workerProcess = child_process.exec('python3 test.py '+i, function (error, stdout, stderr) {
  if (error) {
      console.log(error.stack);
      console.log('Error code: '+error.code);
      console.log('Signal received: '+error.signal);
  }
  console.log('stdout: ' + stdout);
  console.log('stderr: ' + stderr);
});

workerProcess.on('exit', function (code) {
  console.log('子进程已退出,退出码 '+code);
});
            
          

 

  • spawn-child_process.spawn   

使用指定的命令行参数创建进程。

示例:

            
              var child_process = require('child_process');

var workerProcess = child_process.spawn('python3', ['test.py']);

workerProcess.stdout.on('data', function (data) {
  console.log('stdout: ' + data);
});

workerProcess.stderr.on('data', function (data) {
  console.log('stderr: ' + data);
});

workerProcess.on('close', function (code) {
  console.log('子进程已退出,退出码 ' + code);
});
            
          

 

  • fork-child_process.fork             

是spawn()的特殊形式,用于在子进程中运行模块,与spawn方法不同的是,fork会在父进程与子进程之间,建立一个通信管道,用于进程之间的通信。

暂无示例

 

3. 比较exec和spawn

  1. exec将子进程输出结果暂放在buffer中,在结果完全返回后,再将输出一次性的以回调函数返回。如果exec的buffer体积设置的不够大,它将会以一个“maxBuffer exceeded”错误失败告终。而spawn在子进程开始执行后,就不断的将数据从子进程返回给主进程,它没有回调函数,它通过流的方式发数据传给主进程,从而实现了多进程之间的数据交换。
  2. 书写上,exec更方便一些,将整个命令放在第一个参数中,而spqwn需要拆分。
    child_process.spawn('python3', ['test.py', i])
    child_process.exec('python3 test.py '+i, callback)
  3. exec比spawn多了一些默认的option

 

4.解决 Error: maxBuffer exceeded

 

问题描述:

在使用子进程期间遇到了问题 Error: stderr maxBuffer exceeded ,然后 子进程挂掉。

 

原因:

让我们从源码上解释子进程为什么子进程会挂掉?

            
              child.stderr.addListener('data', function(chunk) {
    stderrLen += chunk.length;
 
    if (stderrLen > options.maxBuffer) {
      ex = new Error('stderr maxBuffer exceeded.');
      kill();
    } else {
      if (!encoding)
        _stderr.push(chunk);
      else
        _stderr += chunk;
    }
});

            
          

以上代码逻辑:

记录子进程的log大小,一旦超过 maxBuffer kill 掉子进程。

而当我们在使用 exec 时,不知道设置 maxBuffer ,默认的 maxBuffer 是200K,当我们子进程日志达到200K时,自动 kill() 掉了。

            
              // exec 默认的参数
var options = {
    encoding: 'utf8',
    timeout: 0,
    maxBuffer: 200 * 1024,
    killSignal: 'SIGTERM',
    cwd: null,
    env: null
};

            
          

 

解决方案

知道上面原因了,解决方案就有几个了:

  1. 子进程的系统,不再输出日志
  2. maxBuffer这个传一个足够大的参数
  3. 直接使用spawn,放弃使用exec

我这里采用的是第三种直接使用 spawn ,解除 maxBuffer 的限制,个人觉得最优的方案。因为exec本身就是

 

结束

node文件读写+node执行python文件_第1张图片

 

 


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论