Node学习笔记(1) - 文件操作

Node学习笔记(1)-文件操作

术语解释
双工流可读可写的流

监听一个文件

chalk是给终端输出染色的插件

const fs = require('fs');
var chalk = require('chalk');
var num=0;
fs.watch('target.txt',()=>{
    num++;
    console.log("file changed" + num)
});
console.log(chalk.red("文件正在被监听"));

:::waring
一次保存 出现好几次好几次回调。出现这种是因为操作系统对文件变化的处理方式有关,主要是在mac和windows上
:::

fs.watch(filename[, options][, listener])
  • filename | |

  • options |

    • persistent 指示如果文件已正被监视,进程是否应继续运行。默认值: true。
    • recursive 指示应该监视所有子目录,还是仅监视当前目录。这适用于监视目录时,并且仅适用于受支持的平台(参阅注意事项)。默认值: false。 备注:只有windows和mac支持
    • encoding 指定用于传给监听器的文件名的字符编码。默认值: ‘utf8’。
  • listener | 默认值: undefined。

    • eventType
    • filename |
  • 返回: <fs.FSWatcher>

接收命令行参数

增加了一个小功能,通过命令行输入需要被监听的文件

const fs = require('fs');
const filename = process.argv[2];
const chalk = require('chalk');
if(!filename) {
    throw Error(' a file required');
}
fs.watch(filename,()=>{console.log(chalk.red("文件变更"))});
console.log(chalk.green("文件正在被监听"))
注意:所有未捕获的异常导致Node.js 执行进程退出。
process.argv

process.argv 属性返回一个数组,其中包含当启动 Node.js 进程时传入的命令行参数。 第一个元素是 process.execPath。 如果需要访问 argv[0] 的原始值,参阅 process.argv0。 第二个元素将是正在执行的 JavaScript 文件的路径。 其余元素将是任何其他命令行参数。

创建子进程

继续优化监听程序 在监听到文件变化后创建一个子进程,下面是代码

const fs = require('fs');
var chalk = require('chalk');
const spawn = require('child_process').spawn;
const filename = process.argv[2];
if (!filename) {
    console.log(chalk.red('缺少命令行参数'))
} else {
    fs.watch('target.txt', () => {
        const ls = spawn('ls',['-l','-h',filename]);
        ls.stdout.pipe(process.stdout) //利用管道函数 把childprocess 输出的stream 转换成标准输出 
    });
    console.log(chalk.red("文件正在被监听"));
}
child_process.spawn(command[, args][, options])

child_process.spawn() 方法使用给定的 command 衍生一个新进程,并带上 args 中的命令行参数。 如果省略 args,则其默认为一个空数组。

  • command 要运行的命令
  • args <string[]> 字符串参数的列表
  • options
    • cwd 子进程的当前工作目录。
    • env 环境变量的键值对。
    • argv0 显式地设置发送给子进程的 argv[0] 的值。如果没有指定,则将会被设置为 command 的值。
    • stdio | 子进程的 stdio 配置。参阅 options.stdio。
    • detached 准备子进程独立于其父进程运行。具体行为取决于平台,参阅 options.detached。
    • uid 设置进程的用户标识,参阅 setuid(2)
    • gid 设置进程的群组标识,参阅 setgid(2)
    • shell | 如果为 true,则在 shell 中运行 command。 在 UNIX 上使用 ‘/bin/sh’,在 Windows 上使用 process.env.ComSpec。 可以将不同的 shell 指定为字符串。 参阅 shell 的要求与 Windows 默认的 shell。 默认值: false(没有 shell
    • windowsVerbatimArguments 在 Windows 上不为参数加上引号或转义。在 Unix 上忽略。如果指定了 shell 并且是 CMD,则自动设为 true。默认值: false
    • windowsHide 隐藏子进程的控制台窗口(在 Windows 系统上通常会创建)。默认值: false。
  • 返回:
使用EventEmitter获取数据

修改代码到如下(注意下 这段代码在windows环境下会抛错)

const fs = require('fs');
var chalk = require('chalk');
const spawn = require('child_process').spawn;
const filename = process.argv[2];
if (!filename) {
    console.log(chalk.red('缺少命令行参数'))
} else {
    fs.watch(filename, () => {
        const ls = spawn('ls',['-l','-h',filename]);
        let output = '';
        ls.stdout.on('data', chunk => output+=chunk);
        ls.on('close', () => {
            const parts = output.split(/\s+/);
            console.log(parts[0],parts[4],parts[8])
        })
        ls.on('error',(error)=>{
            console.log(error)
        })
    });
    console.log(chalk.green("文件正在被监听"));
}

在js里面一个非string添加到string里面时具体到buffer对象,当它跟一个string相加时,会把这个二进制数据复制到node.js的堆栈中使用默认编码(utf-8)

这是一个及其消耗性能的行为 注意不要这么玩

ls.stdout返回的是一个EventEmitter类

emitter.on(eventName, listener)
  • eventName | 事件名称。
  • listener 回调函数。
  • 返回: 便于链式调用
异步读写文件

代码如下,主要用到了两个api

普通版

const fs =require('fs');
const chalk = require('chalk');
fs.readFile('target.txt',(err,data)=>{
    if(err){
        throw err
    }else{
        console.log(chalk.blue(data.toString()))
    }
    fs.writeFile('target.txt','Hello Node',(err)=>{
        if(!err){
            console.log(chalk.green("写入成功"))
        }
    })
})

这里插一下,为了方便操作异步数据流 和学习rxjs 这里对上面的代码用rxjs 改装一下

rxjs版本

const fs = require('fs');
const chalk = require('chalk');
var Rx = require('rxjs/Rx');
var read = Rx.Observable.bindNodeCallback(fs.readFile);
read('target.txt').subscribe((data) => {
    console.log(chalk.blue(data.toString()))
},(err)=>{
    throw err
})
❤️ fs.readFile(path[, options], callback)
  • path | | | 文件名或文件描述符。
  • options | 。
    • encoding | 默认值: null。
    • flag 参阅支持的文件系统标志。默认值: ‘r’。
  • callback (err,data)=>{}
❤️ fs.writeFile(file, data[, options], callback)

异步地将数据写入到一个文件,如果文件已存在则覆盖该文件。 data 可以是字符串或 buffer。

  • file | | | 文件名或文件描述符。
  • data | | |
  • options |
    • encoding | 默认值: ‘utf8’。
    • mode 默认值: 0o666。
    • flag 参阅支持的文件系统标志。默认值: ‘w’。
  • callback
    • err
❤️ fs.read(fd, buffer, offset, length, position, callback)

参数表

参数备注
fd从指定的文件中读取数据
buffer数据流缓冲区
offset是 buffer 中开始写入的偏移量
length是一个整数,指定要读取的字节数
position参数指定从文件中开始读取的位置。 如果 position 为 null,则从当前文件位置读取数据,并更新文件位置。 如果 position 是整数,则文件位置将保持不变。
callback回调有三个参数 (err, bytesRead, buffer)
创建读/写流
const fs = require('fs');
const chalk = require('chalk');
//第一种直接输出的方式
fs.createReadStream(process.argv[2]).pipe(process.stdout);
//第二种监听文件流的方式
fs.createReadStream(process.argv[2]).on('data',chunk=>console.log(chalk.green(chunk.toString())));
Tips
  • 如何从process.arvg获取需要创建的子进程

    spawn()返回

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值