对文件的各种操作,使用姿势如下

文件操作单例
@example fu.exist(file); //是否存在
fu.copy(file, 'new-path'); //复制到某个新目录
fu.move(file, 'new-path'); //移动到某个新目录
fu.rename(file, 'new-name');
fu.delete(file); //删除文件或文件夹 fu.mkdir(src); //创建目录
fu.touch(my-file-name); //创建文件 fu.write(my-file-name, data); //写入内容
fu.append(my-file-name, append_data); //追加内容
fu.read(my-file-name); //读取内容 fu.type(my-file-name); //类型 fu.extname(my-file-name); //文件后缀, 带.
fu.extname(my-file-name); //文件后缀,不带. fu.copy('tmp', 'tmp2'); //复制文件或者文件夹tmp中的文件到目录tmp2
fu.move('tmp', 'tmp2'); //移动文件或者文件夹tmp中的文件到文件夹tmp2 fu.each(src, function(item){
console.log('遍历文件');
}); //异步的方式遍历
var options = {
sync: false,
matchFunction: function(itm){
return item.name.match(/\.css$/i);
}
}
var onComplete = function(){
console.log('遍历完成');
}
fu.each(src, function(item), options, onComplete);

在node中通过require('fu.js')即可,源码如下:

/**
* Created by Sorrow.X on 2017/6/16.
*/
const fs = require('fs');
const path = _path = require('path');
const util = require('util'); let isWindows = !!process.platform.match(/^win/);
let wrench = {
// 同步递归创建目录
mkdirSyncRecursive: function (path, mode) {
path = _path.normalize(path);
let self = this;
try {
fs.mkdirSync(path, mode);
} catch (err) {
if (err.code == "ENOENT") {
let slashIdx = path.lastIndexOf(_path.sep); if (slashIdx > 0) {
let parentPath = path.substring(0, slashIdx);
self.mkdirSyncRecursive(parentPath, mode);
self.mkdirSyncRecursive(path, mode);
} else {
throw err;
};
} else if (err.code == "EEXIST") {
return;
} else {
throw err;
};
};
}, // 同步递归删除目录
rmdirSyncRecursive: function (path, failSilent) {
let files;
let self = this;
try {
files = fs.readdirSync(path);
} catch (err) {
if (failSilent) return;
throw new Error(err.message);
}; /* Loop through and delete everything in the sub-tree after checking it */
for (var i = 0; i < files.length; i++) {
var file = _path.join(path, files[i]);
var currFile = fs.lstatSync(file); if (currFile.isDirectory()) {
// Recursive function back to the beginning
self.rmdirSyncRecursive(file);
} else if (currFile.isSymbolicLink()) {
// Unlink symlinks
if (isWindows) {
fs.chmodSync(file, 666) // Windows needs this unless joyent/node#3006 is resolved..
};
fs.unlinkSync(file);
} else {
// Assume it's a file - perhaps a try/catch belongs here?
if (isWindows) {
fs.chmodSync(file, 666) // Windows needs this unless joyent/node#3006 is resolved..
};
fs.unlinkSync(file);
};
}; /* Now that we know everything in the sub-tree has been deleted, we can delete the main
directory. Huzzah for the shopkeep. */
return fs.rmdirSync(path);
}, // 同步拷贝文件
copyFile: function (src, dest) {
let len = 64 * 1024;
let buff = new Buffer(len);
let fdr = fs.openSync(src, 'r');
let fdw = fs.openSync(dest, 'w');
let bytesRead = 1;
let pos = 0;
while (bytesRead > 0) {
bytesRead = fs.readSync(fdr, buff, 0, len, pos);
fs.writeSync(fdw, buff, 0, bytesRead);
pos += bytesRead;
}
fs.closeSync(fdr);
fs.closeSync(fdw);
}
}; // 判断fn是否是函数
let isFunction = function (fn) {
return Object.prototype.toString.call(fn) == '[object Function]';
}; // 判断str是否是字符串
let isString = function (str) {
return Object.prototype.toString.call(str) == '[object String]';
}; /**
文件操作单例
@example fu.exist(file); //是否存在
fu.copy(file, 'new-path'); //复制到某个新目录
fu.move(file, 'new-path'); //移动到某个新目录
fu.rename(file, 'new-name');
fu.delete(file); //删除文件或文件夹 fu.mkdir(src); //创建目录
fu.touch(my-file-name); //创建文件 fu.write(my-file-name, data); //写入内容
fu.append(my-file-name, append_data); //追加内容
fu.read(my-file-name); //读取内容 fu.type(my-file-name); //类型 fu.extname(my-file-name); //文件后缀, 带.
fu.extname(my-file-name); //文件后缀,不带. fu.copy('tmp', 'tmp2'); //复制文件或者文件夹tmp中的文件到目录tmp2
fu.move('tmp', 'tmp2'); //移动文件或者文件夹tmp中的文件到文件夹tmp2 fu.each(src, function(item){
console.log('遍历文件');
}); //异步的方式遍历
var options = {
sync: false,
matchFunction: function(itm){
return item.name.match(/\.css$/i);
}
}
var onComplete = function(){
console.log('遍历完成');
}
fu.each(src, function(item), options, onComplete);
**/
let FileUtil = (function () { // 属性
function F() { }; // 方法
F.prototype = {
constructor: F, /**
判断某个或某些文件(夹)是否存在
@method exist
@param {String} f 一个文件(夹)名称
@return Boolean 文件是否存在
**/
exist: function (f) {
return fs.existsSync(f);
}, /**
是否是文件
@method isFile
@static
@param {String} f 文件名称
@return Boolean 是否是文件
**/
isFile: function (f) {
return this.exist(f) && fs.statSync(f).isFile();
}, /**
是否是文件夹
@method isDirectory
@static
@param {String} f 文件名称
@return Boolean 是否是文件夹
**/
isDirectory: function (f, dir) {
return this.exist(f) && fs.statSync(f).isDirectory();
}, /**
@method extname
@param {String} f 文件名称
@param {String} (optional) withDot 是否带上.
@return String 文件后缀
@example
console.log(fu.extname('image.jpg')); // jpg
**/
extname: function (f, withDot) {
var extname = path.extname(f);
if (!withDot && extname && extname.charAt(0) == '.') {
return extname.substr(1);
}
return extname;
}, /**
创建目录
@method mkdir
@param {String|Array} f 一个或多个文件夹
@param {Number} permission 文件权限
@example
fu.mkdir('model');
fu.mkdir(['view', 'controller']);
fu.mkdir('mydir', 0775);
**/
mkdir: function (f, permission) {
if (util.isArray(f)) {
var self = this;
f.forEach(function (item) {
self.mkdir(item, permission);
})
} else {
if (!this.exist(f)) {
wrench.mkdirSyncRecursive(f, permission || 0777);
}
}
}, /**
创建文件
@method touch
@param {String|Array} f 一个或多个文件
@param {int} (optional)[0777] permission 文件权限
@param {String} (optional) data 文件内容
@example
fu.touch('README.md');
fu.touch('app.js', 0777);
fu.touch(['view/view.js', 'model/model.js']);
fu.touch('app.js', 0777, 'window.app = (function(){ return "app" })()');
**/
touch: function (f, permission, data) {
if (util.isArray(f)) {
var self = this;
f.forEach(function (item) {
self.touch(item, permission);
})
} else {
data = data || '';
this.mkdir(path.dirname(f));
this.write(f, data);
}
}, /**
删除文件或文件夹
@method delete
@param {String|Array} f 一个或多个文件或文件夹
@example
fu.delete('/var/www/tmp/data/one.txt');
fu.delete('/var/www/tmp/data/')
**/
delete: function (f) {
if (util.isArray(f)) {
var self = this;
f.forEach(function (item) {
self.delete(item);
})
} else {
if (this.exist(f)) {
if (this.isDirectory(f)) {
wrench.rmdirSyncRecursive(f, true);
} else {
fs.unlinkSync(f);
}
}
}
}, /**
读取文件内容
@method read
@param {String} f 文件名
@param {String} (optional) encoding 编码,默认`utf-8`
@example
fu.read('文件名');
**/
read: function (f, encoding) {
return fs.readFileSync(f, encoding || 'utf-8');
}, /**
写入内容到文件 (会覆盖以前的内容)
@method read
@param {String} f 文件名
@param {String} data 文件内容
@param {String} (optional) encoding 编码,默认`utf-8`
@example
fu.write('README.md', '你的数据');
**/
write: function (f, data, encoding) {
return fs.writeFileSync(f, data, encoding || 'utf-8');
}, /**
追加内容到文件
@method append
@static
@param {String} f 文件名
@param {String} data 文件内容
@param {String} (optional) encoding 编码,默认`utf-8`
@example
fu.append('README.md', '你的数据');
**/
append: function (f, data, encoding) {
return fs.appendFileSync(f, data, encoding);
}, /**
更改名称
@method rename
@param {String} name 文件名
@param {String} (optional) newName 新的文件名
@example
fu.rename('app.js', 'app_bak.js');
fu.rename('app.js', '/usr/local/bak/app.js');
**/
rename: function (name, newName) {
this.mkdir(path.dirname(newName));
fs.renameSync(name, newName);
}, /**
移动文件或文件夹中的文件到新的目录(移动完可以重命名)
@method move
@param {String|Array} f 一个或多个文件
@param {String} target 目标文件目录
@param {String} (optional) filter_or_newName 过滤正则或者过滤函数或者新名称
@example
//移动js文件
fu.move(fu.list(src), targetDir, /\.js$/i);
fu.move(fu.list(src), targetDir, function(f) {
return f.match(/\.js$/i);
});
//移动并且改名
fu.move('src/app.js', 'dest', 'app-min.js');
**/
move: function (f, target, filter_or_newName) {
var self = this;
var isValid = function (item) {
if (self.isDirectory(item)) {
return true;
};
if (filter_or_newName) {
if (util.isRegExp(filter_or_newName)) {
return filter_or_newName.test(item);
} else if (isFunction(filter_or_newName)) {
return filter_or_newName(item);
};
};
return true;
};
if (util.isArray(f)) {
f.forEach(function (item) {
self.move(item, target);
});
} else {
var name;
if (!isValid(f)) {
return;
};
if (filter_or_newName && isString(filter_or_newName)) {
name = filter_or_newName;
filter_or_newName = null;
} else {
name = path.basename(f);
};
var newName = path.normalize(target + path.sep + name); try {
//如果是文件
if (this.isFile(f)) {
this.rename(f, newName);
};
//如果没有过滤参数
if (!filter_or_newName) {
return this.rename(f, target);
}; //可能有过滤,被过滤掉的文件不能被移动
var deleteList = [];
this.each(f, function (item) {
var dir, t;
if (item.directory) {
dir = path.relative(f, item.name);
t = path.normalize(target + path.sep + dir);
self.mkdir(t);
deleteList.push(item.name);
} else {
dir = path.dirname(path.relative(f, item.name))
t = path.normalize(target + path.sep + dir);
self.move(item.name, t, filter_or_newName);
};
}, {
matchFunction: function (item) {
return isValid(item.name);
}
}); deleteList.forEach(function (item) {
self.delete(item);
});
self.delete(f); } catch (err) {
if (this.isFile(f)) {
this.copy(f, target, filter_or_newName);
this.delete(f);
} else if (this.isDirectory(f)) {
this.copy(f, target, filter_or_newName);
this.delete(f);
};
};
};
}, /**
复制文件或文件夹中的文件到新的目录(复制完可以重命名)
@method copy
@param {String|Array} f 一个或多个文件
@param {String} target 目标文件目录
@param {String} (optional) filter_or_newName 过滤正则或者过滤函数或者新名称
@example
//拷贝js文件
fu.copy(fu.list(src), targetDir, /\.js$/i);
fu.copy(fu.list(src), targetDir, function(f){
return f.match(/\.js$/i);
});
//拷贝并且改名
fu.copy('src/app.js', 'dest', 'app-min.js');
**/
copy: function (f, target, filter_or_newName) {
var self = this;
var isValid = function (item) {
if (self.isDirectory(item)) {
return true;
};
if (filter_or_newName) {
if (util.isRegExp(filter_or_newName)) {
return filter_or_newName.test(item);
} else if (isFunction(filter_or_newName)) {
return filter_or_newName(item);
};
};
return true;
};
if (util.isArray(f)) {
f.forEach(function (item) {
// self.copy(item, dir);
self.copy(item, target);
});
} else {
var name;
if (!isValid(f)) {
return;
};
if (filter_or_newName && isString(filter_or_newName)) {
name = filter_or_newName;
filter_or_newName = null;
} else {
name = path.basename(f);
}; var newName = path.normalize(target + path.sep + name); if (this.isFile(f)) {
this.mkdir(path.dirname(newName));
wrench.copyFile(f, newName);
} else if (this.isDirectory(f)) {
this.each(f, function (item) {
var dir, t;
if (!item.directory) {
dir = path.dirname(path.relative(f, item.name));
t = path.normalize(target + path.sep + dir);
self.copy(item.name, t, filter_or_newName);
};
});
};
};
}, /**
遍历目录下的文件和文件夹
@method each
@static
@param {String} dir 目录
@param {Function} callback 遍历时的回调函数
@param {Object} options 过滤参数
@param {Boolean} options.recursive 是否遍历子文件夹,默认true
@param {Boolean} options.excludeFile 是否屏蔽文件
@param {Boolean} options.excludeDirectory 是否屏蔽文件夹
@param {Boolean} options.sync 是否异步,默认同步
@param {Function} options.matchFunction 匹配函数
@param {Function} (optional) onComplete 完成文件遍历的回调函数
@example
// 同步遍历
fu.each('src', function(item){
console.log(item);
}, {
excludeDirectory: true,
matchFunction: function(item){
return item.filename.match(/\.js/i);
}
}); //以异步方式调用
fu.each('src', function(item){
console.log(item.filename);
}, { sync: false}, function(){
console.log('读取完毕')
});
**/
each: function (dir, callback, options, onComplete) {
options = options || {};
dir = dir.replace(/(\/+)$/, ''); let self = this;
let sync = options.sync != undefined ? options.sync : true;
let excludeFile = options.excludeFile;
let excludeDirectory = options.excludeDirectory;
let matchFunction = options.matchFunction;
let breakFunction = options.breakFunction;
let preventRecursiveFunction = options.preventRecursiveFunction;
let recursive = true;
let checkCount = 0;
let p, i, l; var onFinished = function () {
if (checkCount <= 0 && onComplete) {
onComplete();
};
}; if (options.recursive === false) {
recursive = false;
}; if (!this.isDirectory(dir)) {
onFinished();
return [];
}; var handleItem = function (filename) {
var name = dir + path.sep + filename;
var isDir = self.isDirectory(name);
var info = {
directory: isDir,
name: name,
filename: filename
}; if (isDir) {
if (recursive) {
if (!preventRecursiveFunction || !preventRecursiveFunction(info)) {
checkCount++;
self.each(name, callback, options, function () {
checkCount--;
onFinished();
});
};
}; if (!excludeDirectory) {
if (!matchFunction || (matchFunction && matchFunction(info))) {
callback(info);
};
};
} else if (self.isFile(name)) {
if (!excludeFile) {
if (!matchFunction || (matchFunction && matchFunction(info))) {
callback(info);
};
};
};
checkCount--;
onFinished();
};
if (sync) {
p = fs.readdirSync(dir);
p.forEach(handleItem);
checkCount = 0;
onFinished();
} else {
fs.readdir(dir, function (e, arr) {
if (e) {
onFinished();
} else {
checkCount = arr.length;
onFinished();
arr.forEach(function (item) {
handleItem(item);
});
};
});
};
}, /**
列出目录下的文件和文件夹
@method list
@static
@param {String} dir 目录
@param {Object} options 过滤参数
@param {Boolean} options.recursive 是否遍历子文件夹,默认true
@param {Boolean} options.excludeFile 是否屏蔽文件
@param {Boolean} options.excludeDirectory 是否屏蔽文件夹
@param {Function} options.breakFunction 终止函数
@param {Function} options.matchFunction 匹配函数
@param {Boolean} fullView 是否返回更完整的文件信息
@return Array 文件和文件夹信息
@example
//列出所有js文件
var list = fu.list('aa', {
excludeDirectory: true,
matchFunction: function(item){
return item.filename.match(/\.js$/i);
}
});
console.log(list); //list = ['a.js', 'b/c.js', ...] //列出所有js文件,包含完整信息
var list = fu.list('aa', {
excludeDirectory: true,
matchFunction: function(item){
return item.filename.match(/\.js$/i);
}
}, true);
console.log(list);
**/
list: function (dir, options, fullView) {
let result = [];
options = options || {};
options.sync = true;
this.each(dir, function (item) {
if (fullView) {
result.push(item);
} else {
result.push(item.name);
}
}, options);
return result;
}
}; //实例容器
let instance; let _static = {
name: 'FileUtil', //获取实例的方法
//返回F的实例
getInstance: function (args) {
if (instance === undefined) {
instance = new F(args);
};
return instance;
}
};
return _static;
})(); let fu = FileUtil.getInstance(); module.exports = fu;

很实用的文件操作库。

node 文件操作的更多相关文章

  1. Node基础篇(文件操作)

    文件操作 相关模块 Node内核提供了很多与文件操作相关的模块,每个模块都提供了一些最基本的操作API,在NPM中也有社区提供的功能包 fs: 基础的文件操作 API path: 提供和路径相关的操作 ...

  2. node 学习笔记 - fs 文件操作

    本文同步自我的个人博客:http://www.52cik.com/2015/12/03/learn-node-fs.html 最近看到群里不少大神都开始玩 node 了,我感觉跟他们步伐越来越大了, ...

  3. node学习笔记3——文件操作fs

    文件操作关键字: http('fs') ——  请求 node 里面的 http 模块 readFile ——  读文件,参数包括 文件名,回调函数 writeFile ——  写文件,参数包括 文件 ...

  4. Node.js文件操作二

    前面的博客 Node.js文件操作一中主要是对文件的读写操作,其实还有文件这块还有一些其他操作. 一.验证文件path是否正确(系统是如下定义的) fs.exists = function(path, ...

  5. Node.js文件操作一

    Node.js和其他语言一样,也有文件操作.先不说node.js中的文件操作,其他语言的文件操作一般也都是有打开.关闭.读.写.文件信息.新建删除目录.删除文件.检测文件路径等.在node.js中也是 ...

  6. node.js零基础详细教程(2):模块化、fs文件操作模块、http创建服务模块

    第二章  建议学习时间4小时  课程共10章 学习方式:详细阅读,并手动实现相关代码 学习目标:此教程将教会大家 安装Node.搭建服务器.express.mysql.mongodb.编写后台业务逻辑 ...

  7. Node.js入门教程 第四篇 (流及文件操作)

    流 Stream是Node.js中的抽象接口,有不少Node.js对象实现自Stream. 所有的Stream对象都是EventEmitter 的实例. 例如:fs模块(用于读写操作文件的模块) fs ...

  8. Node.js核心模块API之文件操作

    参考:https://www.runoob.com/nodejs/nodejs-fs.html 异步I/O 1,文件操作 2,网络操作 在浏览器中也存在异步操作 1,定时任务 2,事件处理 3,Aja ...

  9. node.js整理 02文件操作-常用API

    NodeJS不仅能做网络编程,而且能够操作文件. 拷贝 小文件拷贝 var fs = require('fs'); function copy(src, dst) { fs.writeFileSync ...

随机推荐

  1. 【读书笔记】iOS-自定义URL Scheme注意事项

    如果两个不同的应用注册了同样的URL Scheme,那么后安装的应用会响应符合这种协议格式的URL. 如果你的应用的iPhone和iPad版是各自独立的(即不是Universal类型的),那么你就不应 ...

  2. Apex 的异常处理

    Apex 中的异常处理 在 Apex 中,和其他语言类似,对于异常处理通常使用 try.catch.finally.throw 等关键字. 对于每一个 try 代码段,必须要有至少一个 catch 或 ...

  3. ios开发GCD(2)-dispatch_semaphore_t信号量计数器

    思考:现在有多个线程异步执行,我们想要同时最多只能执行2个或n个,该怎么办? dispatch_semaphore_t 看代码解析: NSLog(@"开始"); dispatch_ ...

  4. Android View体系(二)实现View滑动的六种方法

    1.View的滑动简介 View的滑动是Android实现自定义控件的基础,同时在开发中我们也难免会遇到View的滑动的处理.其实不管是那种滑动的方式基本思想都是类似的:当触摸事件传到View时,系统 ...

  5. 安卓开发之自定义一个view弹出框

    https://www.cnblogs.com/muyuge/p/6152167.html

  6. python进程间通信--信号Signal

    信号signal 是python进程间通信多种机制中的其中一种机制.可以对操作系统进程的控制,当进程中发生某种原因而中断时,可以异步处理这个异常. 信号通过注册的方式‘挂’在一个进程中,并且不会阻塞该 ...

  7. CSS3伪类和伪元素

    作为一个CSS3初学不久者来说,很容易混淆单冒号(:)和双冒号(::)的用法,以为两者可以互换着来使用.我自己之前也混淆过他们,因为两者看起来太相像了,就像孪生兄弟.但实际上,他们的区别还是挺大的,最 ...

  8. python之with语句的原理

    首发时间:2018-02-23 15:28 之前看到一篇博客说博主python面试时遇到面试官提问with的原理,而那位博主的博文没有提及with原理,故有此文. 关于with语句,官方文档中是这样描 ...

  9. 精通initramfs构建step by step

    (一)hello world  一.initramfs是什么  在2.6版本的linux内核中,都包含一个压缩过的cpio格式 的打包文件.当内核启动时,会从这个打包文件中导出文件到内核的rootfs ...

  10. [20171106]修改show spparameter的显示宽度.txt

    [20171106]修改show spparameter的显示宽度.txt --//很多年前做的,修改show parameter的显示宽度.--//链接: [20121023]改变show para ...