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()返回