API Docs for:
Show:

File: lib\FileSystemUtil.js

var fs = require('fs');
var path = require('path');

var _ = require('underscore');

var dbc = require('happy.dbc').DesignByContract;


/**
 * 文件系统帮助函数库。
 * 
 * @static
 * @class FileSystemUtil
 */

var FileSystemUtil = module.exports = {

    /**
     * 递归遍历指定目录下的所有文件。
     * 
     * @static
     * @method eachFileSync
     * @param {String} direction 要遍历的目录
     * @param {RegExp|Function} filter 如果是正则表达,则必须满足正则表达式的要求;如果是函数,则函数的返回值必须为 true,函数的签名为:function(filename){ return true; }。
     * @param {Function} callback 对于遍历到的文件执行的回调函数,该函数如果 return false 会导致遍历终止,函数签名如下:
     *      @param {String} callback.filepath 完整的文件路径
     *      @param {String} callback.filename 文件名 + 文件后缀
     * @param {Boolean} [recursive=true] 是否递归子目录
     * @return
     * @example
        FileSystemUtil.eachFileSync('../FileSystemUtil', /.*\.txt/, function (filepath, filename) {
            console.log(filepath);
            console.log(filename);
        });
     */
    eachFileSync: function (direction, filter, callback, recursive) {
        var me = this;
        dbc.mustBeDefined('direction', direction);
        dbc.mustBeDefined('filter', filter);
        dbc.mustBeDefined('callback', callback);

        if (_.isRegExp(filter)) {
            var regexp = filter;
            var filter = function (filename) {
                return regexp.test(filename);
            }
        }

        if (recursive === undefined) {
            recursive = true;
        }

        var filenames = fs.readdirSync(direction);

        _.each(filenames, function (filename) {
            var filepath = path.join(direction, filename);
            var fileStat = fs.statSync(filepath);

            if (fileStat.isFile() && filter(filename)) {
                return callback(filepath, filename)
            }
            else if (fileStat.isDirectory() && recursive) {
                FileSystemUtil.eachFileSync(filepath, filter, callback, recursive);
            }
        });
    },

    /**
     * 创建目录,解决了fs.mkdirSync只能创建一级子目录的问题。
     * 
     * @static
     * @method mkdirSync
     * @param {String} direction 目录路径
     * @return
     * @example
        FileSystemUtil.mkdirSync('./a/b');
     */
    mkdirSync: function (directory) {
        var me = this;
        dbc.mustBeDefined('directory', directory);

        var pathTokens = path.resolve(directory).split(path.sep);

        var currentDirectory = '';
        _.each(pathTokens, function (pathToken, index) {
            if (index === 0) {
                currentDirectory = pathToken + path.sep;
            }
            else {
                currentDirectory = path.join(currentDirectory, pathToken);
            }

            if (!fs.existsSync(currentDirectory)) {
                fs.mkdirSync(currentDirectory);
            }
        });
    },

    /**
     * 写入文件,解决了fs.writeFileSync写入文件必须要求目录存在的问题。
     * 
     * @static
     * @method writeFileSync
     * @param {String} filename 文件路径
     * @param {String} content 文件内容
     * @param {String} [encoding='utf8'] 文件编码
     * @return
     * @example
        FileSystemUtil.mkdirSync('./a/b');
     */
    writeFileSync: function (filename, content, encoding) {
        var me = this;
        dbc.mustBeDefined('filename', filename);
        dbc.mustBeDefined('content', content);

        encoding = encoding || 'utf8';

        FileSystemUtil.mkdirSync(path.dirname(filename));
        fs.writeFileSync(filename, content, encoding);
    }
}