node文件(夹)操作(相关模块、同步或异步调用、路径模块、文件读取、写入、监视)
文件操作相关模块Node内核提供了很多与文件操作相关的模块,每个模块都提供了一些最基本的操作API,在NPM中也有社区提供的功能包fs:基础的文件操作 APIpath:提供和路径相关的操作 APIreadline:用于读取大文本文件,一行一行读fs-extra(第三方):https://www.npmjs.com/package/fs-extra同步或异步调用fs模块对文件的几乎所有操作都有同步和
文件操作
相关模块
Node内核提供了很多与文件操作相关的模块,每个模块都提供了一些最基本的操作API,在NPM中也有社区提供的功能包
-
fs:基础的文件操作 API
-
path:提供和路径相关的操作 API
-
readline:用于读取大文本文件,一行一行读
-
fs-extra(第三方):https://www.npmjs.com/package/fs-extra
同步或异步调用
fs模块对文件的几乎所有操作都有同步和异步两种形式。例如:readFile() 和 readFileSync()
调用方式 | 阻塞代码执行 | 什么时候回调 | 异常处理 |
---|---|---|---|
同步 - readFileSync | 阻塞 | try catch | |
异步 - readFile | 不阻塞 | 将读取任务下达到任务队列,直到任务执行完成才会回调 | 通过回调函数的第一个参数 |
// 同步
console.time('sync');
try {
var data = fs.readFileSync(path.join('C:\\Users\\iceStone\\Downloads', 'H.mp4'));
} catch (error) {
throw error;
}
console.timeEnd('sync');
// 异步
console.time('async');
fs.readFile(path.join('C:\\Users\\iceStone\\Downloads', 'H.mp4'), (error, data) => {
if (error) throw error;
});
console.timeEnd('async');
路径模块
在文件操作的过程中,都必须使用物理路径(绝对路径),path模块提供了一系列与路径相关的 API
path.join
:拼接多个路径部分,并转化为正常格式path.basename(temp)
:获取路径中的文件名path.basename(temp, '.lrc')
:获取路径中的文件名并排除扩展名process.platform
:操作系统path.delimiter
:路径分隔符process.env.PATH.split(path.delimiter)
:一般用于分割环境变量path.dirname(temp)
:获取一个路径中的目录部分path.extname(temp)
:获取一个路径中最后的扩展名path.parse(temp)
:将一个路径解析成一个对象的形式path.format(pathObject)
:将一个路径对象再转换为一个字符串的形式path.isAbsolute(temp)
:获取一个路径是不是绝对路径path.normalize('.../a.txt')
:将一个路径转换为当前系统默认的标准格式,并解析其中的./和…/path.relative(__dirname, temp)
:获取第二个路径相对第一个路径的相对路径path.resolve(temp, 'c:/', './develop', '../application')
:以类似命令行cd命令的方式拼接路径path.sep
:获取不同平台中路径的分隔符(默认)path === path.win32
:允许在任意平台下以WIN32的方法调用PATH对象path === path.posix
:允许在任意平台下以POSIX的方法调用PATH对象
源码地址:
https://github.com/nodejs/node/blob/master/lib/path.js
文件读取
readFile
fs.readFile(file[, options], callback(error, data))
fs.readFile('c:\\demo\1.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
readFileSync
fs.readFileSync(file[, options])
try {
const data = fs.readFileSync('c:\\demo\1.txt', 'utf8');
console.log(data);
} catch(e) {
// 文件不存在,或者权限错误
throw e;
}
createReadStream
fs.createReadStream(path[, options])
const stream = fs.createReadStream('c:\\demo\1.txt');
let data = ''
stream.on('data', (trunk) => {
data += trunk;
});
stream.on('end', () => {
console.log(data);
});
由于Windows平台下默认文件编码是GBK,在Node中不支持,可以通过iconv-lite解决
Readline模块逐行读取文本内容
const readline = require('readline');
const fs = require('fs');
const rl = readline.createInterface({
input: fs.createReadStream('sample.txt')
});
rl.on('line', (line) => {
console.log('Line from file:', line);
});
文件写入
writeFile
fs.writeFile(file, data[, options], callback(error))
fs.writeFile('c:\\demo\a.txt', new Date(), (error) => {
console.log(error);
});
writeFileSync
fs.writeFileSync(file, data[, options])
try {
fs.writeFileSync('c:\\demo\a.txt', new Date());
} catch (error) {
// 文件夹不存在,或者权限错误
console.log(error);
}
createWriteStream
fs.createWriteStream(path[,option])
var streamWriter = fs.createWriteStream('c:\\demo\a.txt');
setInterval(() => {
streamWriter.write(`${new Date}\n`, (error) => {
console.log(error);
});
}, 1000);
appendFile
fs.appendFile(file,data[,options],callback(err))
// 相比较之前文件流的方式,这种方式不会占用文件资源,append完成就会释放
setInterval(() => {
fs.appendFile('c:\\demo\a.txt',`${new Date}\n`, (error) => {
console.log(error);
});
}, 1000);
appendFileSync
fs.appendFileSync(file,data[,options])
setInterval(() => {
fs.appendFileSync('c:\\demo\a.txt',`${new Date}\n`);
}, 1000);
其他常见文件操作
文件操作 | 异步 | 同步 |
---|---|---|
验证路径是否存在 | fs.exists(path,callback(exists)) | fs.existsSync(path) 返回布尔类型 exists |
获取文件信息 | fs.stat(path,callback(err,stats)) | fs.statSync(path) 返回一个fs.Stats实例 |
移动文件或重命名文件或目录 | fs.rename(oldPath,newPath,callback) | fs.renameSync(oldPath,newPath) |
删除文件 | fs.unlink(path,callback(err)) | fs.unlinkSync(path) |
其他常见文件夹操作
文件夹操作 | 异步 | 同步 |
---|---|---|
创建一个目录 | fs.mkdir(path[,model],callback) | fs.mkdirSync(path[,model]) |
删除一个空目录 | fs.rmdir(path,callback) | fs.rmdirSync(path) |
读取一个目录 | fs.readdir(path,callback(err,files)) | fs.readdirSync(path) 返回files |
文件监视
利用文件监视实现自动 markdown 文件转换
-
相关链接:
- https://github.com/chjj/marked
- https://github.com/Browsersync/browser-sync
-
实现思路:
- 利用
fs
模块的文件监视功能监视指定MD文件 - 当文件发生变化后,借助
marked
包提供的markdown
tohtml
功能将改变后的MD文件转换为HTML - 再将得到的HTML替换到模版中
- 最后利用BrowserSync模块实现浏览器自动刷新
- 利用
const fs = require('fs');
const path = require('path');
var marked = require('marked');
var bs = require('browser-sync').create();
var target = path.join(__dirname, process.argv[2] || './README.md');
var filename = path.basename(target, path.extname(target)) + '.html';
var targetHtml = path.join(path.dirname(target), filename);
bs.init({
server: path.dirname(target),
index: filename,
notify: false
});
bs.reload(filename);
var template = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>{{{styles}}}</style>
</head>
<body>
<article class="markdown">
{{{body}}}
</article>
</body>
</html>
`;
fs.readFile(path.join(__dirname, './markdown.css'), 'utf8', (error, css) => {
if (error) throw error;
template = template.replace('{{{styles}}}', css);
var handler = (current, previous) => {
fs.readFile(target, 'utf8', (error, content) => {
var html = template.replace('{{{body}}}', marked(content));
fs.writeFile(targetHtml, html, (error) => {
if (!error) {
console.log(`updated@${new Date()}`);
bs.reload(filename);
}
});
});
};
handler();
fs.watchFile(target, { interval: 100 }, handler);
});
更多推荐
所有评论(0)