在文件系统中,我们最常用到的就是文件的创建,读取,添加,删除等等,在nodejs中,有一个文件系统模块,在需要操作文件的时候  我们首先需要通过require方法引入这个文件系统模块。如下所示:

var fs=require('fs');

fs一些常见的操作

创建目录

//fs.mkdir(path, [mode], callback);
/**
 * path, 被创建目录的完整路径及目录名;
 * [mode], 目录权限,默认0777
 * [callback(err)], 创建完目录回调函数,err错误对象
 */

fs.mkdir("./test",function (err) {
    if(err){
        throw err;
    }
    console.log('创建目录成功')
});

 获取文件信息

//fs.stat(path, callback);
/**
 * path, 要查看目录/文件的完整路径及名;
 * [callback(err, stats)], 操作完成回调函数;err错误对象,stat fs.Stat一个对象实例,提供如:isFile, isDirectory,isBlockDevice等方法及size,ctime,mtime等属性
 */


fs.stat("./album",function (err,stats) {
    if(err) {
        throw err;
    }
    //判断是否是文件夹,如果是文件夹输出true
    if(stats.isDirectory()){
        console.log(true);
    }
});

读取目录

//使用fs.readdir读取目录,重点其回调函数中files对象
//fs.readdir(path, callback);

/**
 * path, 要读取目录的完整路径及目录名;
 * [callback(err, files)], 读完目录回调函数;err错误对象,files数组,存放读取到的目录中的所有文件名
 */

fs.readdir('./album',function (err,files) {
    if(err) {
        throw err;
    }

    console.log(files);
});

读取文件readFile函数

//readFile(filename,[options],callback);

/**
 * filename, 必选参数,文件名
 * [options],可选参数,可指定flag(文件操作选项,如r+ 读写;w+ 读写,文件不存在则创建)及encoding属性
 * callback 读取文件后的回调函数,参数默认第一个err,第二个data 数据
 */

fs.readFile('./test.txt',  function (err, data) {
    if(err) {
     console.error(err);
     return;
    }
    console.log(data);
});

 把异步变成同步

上面介绍的这些方法都是异步的方法,异步由于不会阻止后续代码的执行,所以有的时候,异步的方式会产生一些问题,如下实例:在该实例中,我们将读取一个目录,判断目录中的文件是不是一个文件夹,如果是一个文件夹,就输出,否则就跳过。解决这个问题的思路是,首先我们读取这个目录,得到这个目录中的所有文件,然后循环遍历得到的文件数组,依次判断文件是不是文件夹,如果是文件夹,就放入到我们事先定义的一个空数组中,循环完之后,我们输出这个数组。代码如下

var http=require("http");
var fs=require("fs");
var server=http.createServer(function (req,res) {
    if(req.url=="/favicon.ico"){
        return;
    }
    /*读取文件*/
    fs.readdir('./album',function (err,files) {
        if(err){
            console.log(err)
        }
        var floderArr=[];//定义一个数组,如果是文件夹,就存放在该数组中
        for(var i=0;i<files.length;i++){
            /*读取文件信息*/
            fs.stat('./album/'+files[i],function (err,stats) {
                if(stats.isDirectory()){
                    floderArr.push(files[i]);
                }
            })
        }

        console.log(floderArr);//输出数组

    })
    res.end();
});

server.listen(3000,"127.0.0.1");

运行结果:

运行上述代码,我们发现,并没有按照我们预先想的,输出一个文件夹的数组,而是输出的一个空数组。这是因为,读取文件这个方法是异步的,他并不会等我们读取完文件再去执行输出数组的操作,而是一开始就回去输出这个数组,所以我们看到的就是输出一个空数组,解决这个问题的方式,我们要将这个方法变成同步的。解决方法如下:我们用一个自执行函数,然后读取完一个文件之后,然后再调用一次该函数,读取下一个文件,直到读取完所有的文件,再输出该数组

var http=require("http");
var fs=require("fs");
var server=http.createServer(function (req,res) {
    if(req.url=="/favicon.ico"){
        return;
    }
    /*读取文件*/
    fs.readdir('./album',function (err,files) {
        if(err){
            console.log(err)
        }
        var floderArr=[];
        (function isFloder(i) {
            if(i==files.length){
                console.log(floderArr);
                return;
            }
            /*读取文件信息*/
            fs.stat('./album/'+files[i],function (err,stats) {
                if(stats.isDirectory()){
                    floderArr.push(files[i]);
                }
                isFloder(i+1);
            })
        })(0);
    })

    res.end();
});

server.listen(3000,"127.0.0.1");

运行结果如下:

通过上面这种方式,我们就把一个异步的方法变成了一个同步的方法,这个案例只是提供一个解决问题的思路,实际上,fs提供了异步的文件操作方法,也提供了同步的文件方法,我们可以看实际需要,选择合适的方法。

静态资源文件管理

/**
 * Created by Danny on 2015/9/20 9:34.
 */
var http = require("http");
var fs = require("fs");
var url = require("url");
var path = require("path");

var server = http.createServer(function(req,res){
    //这里如果不用req.url来if判断,那么用户不管输入什么网址,
    //做的事情都一样啊
    //得到地址
    var pathname = url.parse(req.url).pathname;
    //判断此时用户输入的地址是文件夹地址还是文件地址
    //如果是文件夹地址,那么自动请求这个文件夹中的index.html
    if(pathname.indexOf(".") == -1){
        pathname += "/index.html";
    }
    //输入的网址是127.0.0.1/images/logo.png
    //实际请求的是./static/images/logo.png
    var fileURL = "./" + path.normalize("./static/" + pathname);
    //得到拓展名
    var extname = path.extname(pathname);

    //把文件读出来
    fs.readFile(fileURL,function(err,data){
        //读完之后做的事情
        if(err){
            //文件不存在
            res.writeHead(404,{"Content-Type":"text/html;charset=UTF8"})
            res.end("404,页面没有找到");
        }
        //读完之后做的事情
        getMime(extname,function(mime){
            res.writeHead(200,{"Content-Type":mime})
            res.end(data);
        });
    });
});

server.listen(80,"127.0.0.1");

function getMime(extname,callback){
    //读取mime.json文件,得到JSON,根据extname key ,返回对应的value
    //读取文件
    fs.readFile("./mime.json",function(err,data){
        if(err){
            throw Error("找不到mime.json文件!");
            return;
        }
        //转成JSON
        var mimeJSON = JSON.parse(data);
        var mime =  mimeJSON[extname]  || "text/plain";
        //执行回调函数,mime类型字符串,就是它的参数,因为readFile是一个异步的方法,所以这里需要用到回调函数,直接把操作写在回调里面
        callback(mime);
    });
}

 

posted on 2017-11-24 13:34  小之  阅读(1045)  评论(0编辑  收藏  举报