Node.js的文件系统

Node.js的文件系统

JavaScript的是没有操作文件的能力,但是Node.js是可以做到的。
Node.js提供了操作文件的接口,但是接口有太多。主要使用一些常用的接口。

文件系统模块是一个封装了标准的 POSIX 文件 I/O 操作的集合。通过 require('fs') 使用这个模块。所有的方法都有同步和异步两种模式。

Node.js的文件系统API

1.读取文件
Node.js提供了两种方式读取文件,一个是异步的方式读取文件,一个是同步的方式读取文件。


var fs = require("fs");
// 我们来定义一个函数,用来读取文件
function readFile (fileUrl) {
  console.log("--开始读取--");
  fs.readfile(fileUrl,function(err,data){
    if(err){
      console.log("--读取失败--")
    }
    console.log("读取到的数据是:"+data.toString());
  })
}
readFile("./src/test.txt");
// 执行函数,就能读取到文件的信息
// 上边是异步读取数据,同步读取数据是
// 同步读取函数
function readFileSync(fileUrl) {
    console.log("----开始同步读取----");
    var data = fs.readFileSync(fileUrl);
    console.log("同步读取的数据是" + data.toString());
    console.log("----读取结束----")
}
readFileSync("./src/test.txt");
// 推荐使用异步读取数据,速度快,性能好,不会阻塞;

2.写入文件

// fs.writeFile(filename,data,[options],callback);
/**
 * filename, 必选参数,文件名
 * data, 写入的数据,可以字符或一个Buffer对象
 * [options],flag,mode(权限),encoding,都是选填
 * callback 读取文件后的回调函数,参数默认err
 */
// 写文件
var w_data = "我是写入的内容";
fs.writeFile("./src/test.txt",w_data,function (err) {
  if (err) {
    console.error(err);
  }
  console.log("写入成功")
})
// 有一点不得不提,就是如果你写入的文件是已经存在的文件,那么之前的内容会被覆盖掉。
// 下边的方法就是把你写入内容追加到原来的文件中;

3.追加内容


// fs.appendFile(filename,data,[options],callback)
/**
 * filename,必填参数,文件名
 * data,追加的内容
 * options,选填,flag,mode。。。
 * callback,默认参数err
 */
// 追加内容
var appendData = "我是被追加的内容";
fs.appendFile("./src/test.txt",appendData,function (err) {
  if (err) {
    console.error(err);
  }
  console.log("追加内容成功!")
})

4.关于打开文件,读取文件, 截取文件,写入文件,关闭文件,

4.1 先来看看打开文件

fs.open(filename,flag,[mode],callback)
参数说明
/**
 * filename,必填参数
 * flags,必填参数,详细参考这些参数设置
 * mode,选填,设置权限
 * callback,默认参数第一个err,第二个fd,这个fd是个啥玩意,解释如下
 * fd为一个整数,表示打开文件返回的文件描述符,window中又称文件句柄
 */
/*Flag  描述
r   以读取模式打开文件。如果文件不存在抛出异常。
r+  以读写模式打开文件。如果文件不存在抛出异常。
rs  以同步的方式读取文件。
rs+ 以同步的方式读取和写入文件。
w   以写入模式打开文件,如果文件不存在则创建。
wx  类似 'w',但是如果文件路径存在,则文件写入失败。
w+  以读写模式打开文件,如果文件不存在则创建。
wx+ 类似 'w+', 但是如果文件路径存在,则文件读写失败。
a   以追加模式打开文件,如果文件不存在则创建。
ax  类似 'a', 但是如果文件路径存在,则文件追加失败。
a+  以读取追加模式打开文件,如果文件不存在则创建。
ax+ 类似 'a+', 但是如果文件路径存在,则文件读取追加失败。
*/

一个实例写法:

fs.open("./src/test.txt","r+",function (err,fd) {
  if (err) {
    console.error(err);
  }
  console.log(fd)// fd 是一个windows系统的句柄,类似于给文件一个标识,后边会用到
  // 还记得定时器么,浏览器就会给每个定时器一个id,我们每次清除定时器,就是清除对应id的定时器
  console.log("文件被打开了")
  // 文件被打开,但是,是在内存中打开的,你根本看不到的,不用在这做纠结。
})

4.2 读取文件
文件被打开了,那么我肯定是要读取的呀!

file.read(filename,buffer,offset,length,position,callback)
/**
 * fd, 使用fs.open打开成功后返回的文件描述符
 * buffer, 一个Buffer对象,v8引擎分配的一段内存
 * offset, 整数,向缓存区中写入时的初始位置,以字节为单位
 * length, 整数,读取文件的长度
 * position, 整数,读取文件初始位置;文件大小以字节为单位
 * callback(err, bytesRead, buffer), 读取执行完成后回调函数,bytesRead实际读取字节数,被读取的缓存区对象
 */
 

读取文件的实例:

fs.open("./src/test.txt","r+",function (err,fd) {
    if (err) {
        console.error(err)
    }
    console.log("文件被打开了")
    console.log("准备读取文件");
    var buffer = new Buffer(1024);
    // fd 在read的时候用到了,其实类似于一个文件的标识
    fs.read(fd,buffer,0,buffer.length,0,function (err,bytesRead,buffer) {
        if (err) {
            console.error(err)
        }
        console.log(bytesRead+" 字节被读")
        if (bytesRead>0) {
            console.log("读取的内容"+buffer.toString())
        }
    })
})

4.3 截取文件

fs.// fs.ftruncate(fd,len,callback)
/**
 * fd,打开文件时候的fd
 * len,要截取的长度
 * callback,回调函数,没有参数
 */
 

截取文件实例,截取完成后关闭文件:

// 这是一套,打开文件,截取文件,读取文件,最后关闭文件
fs.open("./src/test.txt","r+",function (err,fd) {
    if (err) {
        console.log(err)
    }
    console.log("打开文件成功!")
    console.log("准备截取文件");
    // 也就是说,文件被截取之后,能读到的就是被截取的部分
    fs.ftruncate(fd,10,function (err) {
        if (err) {
            console.log(err)
        }
        console.log("截取文件成功!");
        console.log("开始读取文件");
        fs.read(fd,buffer,0,buffer.length,0,function (err,bytesRead) {
            if (err) {
                console.error(err)
            }
            console.log(bytesRead+" 字节被读取");
            if (bytesRead>0) {
                console.log(buffer.slice(0,bytesRead).toString())
            }
            // 关闭文件
            fs.close(fd,function (err) {
                if (err) {
                    console.log(err)
                }
                console.log("文件关闭")
            })
        })
    })
})
文件被截取之后,能读到就是被截取的部分

4.4 关闭文件
具体用法,如上例所示

fs.close(fd,callback)
/**
 * fd,打开文件时候的fd
 * callback,回调函数,参数err
 */
 

4.5 写入文件

// fs.write(fd,buffer,offset,length,position,callback);
/**
 * fd, 使用fs.open打开成功后返回的文件描述符
 * buffer, 一个Buffer对象,v8引擎分配的一段内存
 * offset, 整数,从缓存区中读取时的初始位置,以字节为单位
 * length, 整数,从缓存区中读取数据的字节数
 * position, 整数,写入文件初始位置;
 * callback(err, written, buffer), 写入操作执行完成后回调函数,written实际写入字节数,buffer被读取的缓存区对象
 */

写入文件实例:

fs.open("./src/test.txt","r+",function (err,fd) {
    if (err) {
        console.error(err)
    }
    console.log("文件被打开了");
    console.log("准备写入文件");
    var buf = new Buffer("写入的内容");
    fs.write(fd,buf,0,buf.length,0,function (err,written,buffer) {
        if (err) {
            console.error(err)
        }
        // 写入文件的字符数,一个中文,utf8编码三个字节
        console.log(written);
        // 我们会发现之前的text.txt文件被改写了
        console.log(buffer.toString())
    })
    fs.close(fd,function (err) {
        if (err) {
            console.error(err)
        }
        console.log("文件被关闭了")
    })
})

5.获取文件信息

// fs.stat(filename,callback)
/**
 * filename,必填参数,文件路径和文件名称
 * callback,第一个参数err,第二个stats,返回一个文件相关的信息
 */
 

获取文件信息实例:

fs.stat(__dirname+"/test.txt",function (err,stats) {
    if (err) {
        console.error(err)
    }
    console.log(stats)
})

6.创建文件夹


// fs.mkdir(filname,callback)
/**
 * filename,必填参数
 * callback,只有一个err参数
 */
 
 fs.mkdir(__dirname+"/test/",function (err) {
    if (err) {
        console.error(err)
    }
    console.log("文件夹创建成功!")
})

7.读取文件夹

// fs.readdir(filename,{options},callback)
/**
 * filename,必填参数
 * options,选填参数
 * callback,第一个参数err,第二个参数files,返回的是一个文件的数组
 */
 

读取文件夹实例:


// 我们在刚才创建的test文件夹下,添加两个文件看看,一个是index.js,index.html
fs.readdir(__dirname+"/test",function (err,files) {
    if (err) {
        console.error(err)
    }
    console.log("读取文件夹成功!")
    console.log(files)
    files.forEach(function (value,index) {
        console.log(value+"---"+index)
    })
})

8.删除文件

// fs.unlink(filename,callback)
/**
 * filename,必填参数
 * callback,参数err
 */

删除文件的实例:


// 在新建的test文件夹内在新建一个index.txt文件,然后我们再把它删掉
fs.unlink(__dirname+"/test/index.txt",function (err) {
    if (err) {
        console.error(err)
    }
    console.log("删除成功!")
})

9.删除文件夹

fs.rmdir(fliename,callback);
/**
 * filename,必填参数
 * callback,参数err
 */
 
// 清空文件夹,同步操作
function cleanDir(filename) {
    // 采用同步的方式读目标文件夹,获取files对象
    var files = fs.readdirSync(filename);
    // 遍历files对象,直接forEach了
    files.forEach((item) => {
        var stats = fs.statSync(filename+"/"+item);
        // 判断当前是文件还是文件夹
        if (stats.isDirectory()) {
            // 如果是文件夹就重复调用方法
            cleanDir(filename+"/"+item)
        }else{
            // 如果不是文件夹,那就是文件,直接删除
            fs.unlinkSync(filename+"/"+item);
            console.log("删除文件"+filename+"/"+item+"成功")
        }
    })
}

// 删除每个空文件夹,同步操作
function deleteDir(filename) {
    // 同步方式读取文件夹,得到files
    var files = fs.readdirSync(filename);
    // 判断files下是否存在别的文件夹,也就是判断length
    if (files.length>0) {
        var tempFile = 0;
        files.forEach((item) => {
            tempFile++;
            deleteDir(filename+"/"+item);
        })
        // 如果把子文件夹都删除了,那么母文件夹的filename和上述的不同,需要单独列出来,
        // 做一步判断,然后删除母文件夹
        if (tempFile==files.length) {
            fs.rmdirSync(filename)
            console.log("删除文件夹"+filename+"成功")
        }
    }else{
        fs.rmdirSync(filename)
        console.log("删除文件夹"+filename+"成功")
    }
}
cleanDir(__dirname + "/test");
deleteDir(__dirname + "/test");

基本上Node.js的文件系统最常用的api,大体都接触了一遍。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,087评论 18 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,292评论 18 399
  • Node.js是目前非常火热的技术,但是它的诞生经历却很奇特。 众所周知,在Netscape设计出JavaScri...
    w_zhuan阅读 3,577评论 2 41
  • Node.js是目前非常火热的技术,但是它的诞生经历却很奇特。 众所周知,在Netscape设计出JavaScri...
    Myselfyan阅读 4,040评论 2 58
  • 刚认识了一位新朋友,说是朋友,其实她是客户,因为在工作聊得很投机,也就算是一个新朋友吧! 第一次见到她是在11月左...
    郭颜阅读 222评论 0 0