/* create by AlexZ33 */
// fs 模块
var fs = require('fs');
/*
* fs.open(path, flag, [mode], callback)
* path : 要打开的文件路径
* flags: 打开文件的方式 读/写
* mode: 设置文件的模式 读/写/执行 4/2/1 0777
* callback : 回调
* err: 文件打开失败的错误保存在err里,如果成功 err为null
* fd : 被打开文件的标识
*/
fs.open('1.txt','r', function(err, fd) {
console.log(err);
console.log(fd);
})
fs.realpathSync
// Make sure any symlinks in the project folder are resolved:
// https://github.com/facebookincubator/create-react-app/issues/637
const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
https://github.com/1397467062...
fs.readdirSync
fs.statSync
https://github.com/JXtreehous...
fs.readFileSync
fs.stat & fs.statSync
1.异步版:fs.stat(path,callback):
path是一个表示路径的字符串,callback接收两个参数(err,stats),其中stats就是fs.stats的一个实例;
2.同步版:fs.statSync(path)
只接收一个path变量,fs.statSync(path)其实是一个fs.stats的一个实例;
3.再来看fs.stats有以下方法:
stats.isFile()
stats.isDirectory()
stats.isBlockDevice()
stats.isCharacterDevice()
stats.isSymbolicLink() (only valid with fs.lstat())
stats.isFIFO()
stats.isSocket()
fs.accessSync
常用utils
const createFolder = function (folder) {
try {
fs.accessSync(folder);
} catch (e) {
fs.mkdirSync(folder);
}
};
判断目录是否存在
// ignore not exists dir
const exists = await fs.exists(logdir)
if(!exists) return
删除过期文件
https://github.com/eggjs/egg-...
// https://github.com/eggjs/egg-logrotator/blob/master/app/schedule/clean_log.js
// remove expired log files: xxx.log.YYYY-MM-DD
async function removeExpiredLogFile(logdir, maxDays, logger) {
// ignore not exists dir
const exists = await fs.exists(logdir)
if (!exists) return
const files = await fs.readdir(logdir)
const expiredDate = moment().subtract(maxDays, 'days').startOf('date');
const names = files.filter(file => {
const name = path.extname(file).substring(1) // 扩展名去掉第一个点.
if (!/^\d{4}\-\d{2}\-d{2}/.test(name)) {
return false
}
const date = moment(name, 'YYYY-MM-DD').startOf('date')
if (!date.isValid()) {
return false
}
return date.isBefore(expiredDate)
})
if (names.lengh === 0) {
return;
}
console.log(`start remove ${logdir} files: ${names.join(', ')}`)
await Promise.all(names.map(name => {
const logfile = path.join(logdir, name)
return fs.unlink(logfile)
.catch(err => {
err.message = ` remove logfile ${logfile} error, ${err.message}`;
throw new Error(err)
})
}))
````
## 遍历目录下的文件目录
reference : https://github.com/chenshenhai/koa2-note/blob/master/demo/mysql/util/walk-file.js
const fs = require('fs')
/**
- 遍历目录下的文件目录
- @param {string} pathResolve 需进行遍历的目录路径
- @param {string} mime 遍历文件的后缀名
- @return {object} 返回遍历后的目录结果
*/
const getFile = function (pathResolve, mime) {
let files = fs.readdirSync(pathResolve)
let fileList = {}
for (let [i, item] of files.entries()) {
let itemArr = item.split('\.')
let itemMime = (itemArr.length > 1) ? itemArr[itemArr.length - 1] : 'undefined'
let keyName = item + ''
if (mime === itemMime) {
fileList[item] = pathResolve + item
}
}
return fileList
}
## windows下的路径问题
![clipboard.png](/img/bVbxQri)
// useage
const fs = require('fs')
const getFile = require('./fs.js')
function getSqlMap() {
let basePath = __dirname
basePath = basePath.replace(/\/g, '/')
let pathArr = basePath.split('/')
pathArr = pathArr.splice(0, pathArr.length - 1)
basePath = pathArr.join('/') + '/sql/'
// D:/personal/data-manager/app/dao/sql/
let fileList = getFile(basePath, 'sql')
return fileList
}
console.log(getSqlMap())
![clipboard.png](/img/bVbxQwn)
## 递归读取
https://github.com/fs-utils/fs-readdir-recursive
var fs = require('fs')
var path = require('path')
module.exports = read
function read(root, filter, files, prefix) {
prefix = prefix || ''
files = files || []
filter = filter || noDotFiles
var dir = path.join(root, prefix)
// 废弃了 exits
if (!fs.existsSync(dir)) return files
//
if (fs.statSync(dir).isDirectory())
fs.readdirSync(dir)
.filter(function (name, index) {
return filter(name, index, dir)
})
.forEach(function (name) {
read(root, filter, files, path.join(prefix, name))
})
else
files.push(prefix)
return files
}
function noDotFiles(x) {
return x[0] !== '.'
}
## 读取文件树 并判断是否 存在给出的路径
https://github.com/vuejs/vue-next/blob/master/scripts/utils.js
`````
const fs = require('fs')
const targets = (exports.targets = fs.readdirSync('packages').filter(f => {
if (!fs.statSync(`packages/${f}`).isDirectory()) {
return false
}
const pkg = require(`../packages/${f}/package.json`)
if (pkg.private && !pkg.buildOptions) {
return false
}
return true
}))
exports.fuzzyMatchTarget = (partialTargets, includeAllMatching) => {
const matched = []
partialTargets.some(partialTarget => {
for (const target of targets) {
if (target.match(partialTarget)) {
matched.push(target)
if (!includeAllMatching) {
break
}
}
}
})
if (matched.length) {
return matched
} else {
throw new Error(`Target ${partialTargets} not found!`)
}
}
````
# 写操作
````
/*!
* write <https://github.com/jonschlinkert/write>
*
* Copyright (c) 2014-2015, Jon Schlinkert.
* Licensed under the MIT License.
*/
'use strict';
var fs = require('fs');
var path = require('path');
var mkdir = require('mkdirp');
/**
* Asynchronously write a file to disk. Creates any intermediate
* directories if they don't already exist.
*
* ```js
* var writeFile = require('write');
* writeFile('foo.txt', 'This is content to write.', function(err) {
* if (err) console.log(err);
* });
* ```
*
* @name writeFile
* @param {String} `dest` Destination file path
* @param {String} `str` String to write to disk.
* @param {Function} `callback`
* @api public
*/
module.exports = function writeFile(dest, str, cb) {
var dir = path.dirname(dest);
fs.exists(dir, function (exists) {
if (exists) {
fs.writeFile(dest, str, cb);
} else {
mkdir(dir, function (err) {
if (err) {
return cb(err);
} else {
fs.writeFile(dest, str, cb);
}
});
}
});
};
/**
* Synchronously write files to disk. Creates any intermediate
* directories if they don't already exist.
*
* ```js
* var writeFile = require('write');
* writeFile.sync('foo.txt', 'This is content to write.');
* ```
*
* @name writeFile.sync
* @param {String} `dest` Destination file path
* @param {String} `str` String to write to disk.
* @api public
*/
module.exports.sync = function writeFileSync(dest, str) {
var dir = path.dirname(dest);
if (!fs.existsSync(dir)) {
mkdir.sync(dir);
}
fs.writeFileSync(dest, str);
};
/**
* Uses `fs.createWriteStream`, but also creates any intermediate
* directories if they don't already exist.
*
* ```js
* var write = require('write');
* write.stream('foo.txt');
* ```
*
* @name writeFile.stream
* @param {String} `dest` Destination file path
* @return {Stream} Returns a write stream.
* @api public
*/
module.exports.stream = function writeFileStream(dest) {
var dir = path.dirname(dest);
if (!fs.existsSync(dir)) {
mkdir.sync(dir);
}
return fs.createWriteStream(dest);
};
````
# 删除
使用webpack build文件项目时每次都会生成一个dist目录,有时需要把dist目录里的所以旧文件全部删掉,
除了可以使用rm -rf /dist/命令删除外,还可以使用rimraf /dist/命令
`rimraf`的作用:以包的形式包装`rm -rf`命令,用来删除文件和文件夹的,不管文件夹是否为空,都可删除
局部安装:npm install rimraf --save-dev
全局安装:npm install rimraf -g
使用:rimraf <path> \[<path> ...\]
api:rimraf(f, \[opts\], callback)
也可以用封装好的包
- del
https://github.com/sindresorhus/del/blob/master/index.js
# 遍历文件
https://github.com/ks3sdk/ks3-nodejs-sdk/blob/master/lib/util.js
/**
- 遍历文件
*/
function walkFile(p, opt, fileList) {
var fileList = fileList || [];
var _config = {
isDeep: false,
ignore: /\s/ig
};
var dirList = fs.readdirSync(p);
for (var it in opt) {
_config[it] = opt[it];
}
dirList.forEach(function(item) {
if (!_config.ignore.test(item)) {
if (_config.isDeep) {
if (fs.statSync(p + '/' + item).isDirectory()) {
fileList.push(p + '/' + item);
walkFile(p + '/' + item, opt, fileList);
} else {
fileList.push(p + '/' + item);
}
} else {
fileList.push(p + '/' + item);
}
}
});
return fileList;
}
# 遍历文件夹
https://github.com/ks3sdk/ks3-nodejs-sdk/blob/master/lib/util.js
/**
- 遍历文件夹
*/
function walkDir(p, opt) {
var fileList = walkFile(p, opt);
var dirList = [];
fileList.forEach(function(item) {
if (fs.statSync(item).isDirectory()) {
dirList.push(item);
}
});
return dirList;
}
# 给文件夹下文件md5加密
/*
- 为导出的文件生成md5
*/
var fs = require('fs');
var crypto = require('crypto');
var rootPath = '../output/myapp/';
var md5File = 'md5conf.json';
var trimStr = 'myapp';
var removeReg = new RegExp('/' + trimStr + '/', 'g');
var files = fs.readdirSync(rootPath);
var md5Info = {};
// 替换path
files.forEach(function (elem, i) {
var filePath = rootPath + elem;
var stat = fs.statSync(filePath);
if (stat.isFile()) {
var data = fs.readFileSync(filePath, 'utf8');
if(/^.*\.(css|js|html)/.test(elem)) {
console.log('replace', elem);
var newData = data.replace(removeReg, '');
fs.writeFileSync(filePath, newData, 'utf8');
}
}
});
// 计算md5
function calcMd5(path, files) {
files.forEach(function (elem, i) {
var filePath = path + elem;
var stat = fs.statSync(filePath);
if(stat.isDirectory()) {
calcMd5(filePath + '/', fs.readdirSync(filePath));
} else {
var data = fs.readFileSync(filePath);
md5Info[filePath.replace(rootPath, '')] = crypto.createHash('md5').update(data).digest('hex');
}
});
}
calcMd5(rootPath, files);
fs.writeFile(rootPath + md5File, JSON.stringify(md5Info));
# 常见的读写utils
https://github.com/fex-team/fis3/blob/master/lib/util.js
[https://github.com/yantze/fs-lockfile](https://github.com/yantze/fs-lockfile)
# 扩展包
- [fs-extra](https://github.com/jprichardson/node-fs-extra)
使用示例:
https://github.com/1397467062/h5-react/blob/master/H5-react/multipage/scripts/build.js
# 参考
https://www.jianshu.com/p/5683c8a93511
[node命令行工具之实现项目工程自动初始化的标准流程](https://juejin.im/post/5d505356e51d456209238818?utm_source=gold_browser_extension)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。