环境:Node v8.2.1; Npm v5.3.0; OS Windows10html
nodejs的文件操做大部分API都提供了同步和异步的两种方式,下面是异步API结构图,同步方法在异步方法后面加【Sync】就好了node
下面是部分API的例子,对部分API的一个简单代码实现json
//readFile(filename,[options],callback); /** * filename, 必选参数,文件名 * [options],可选参数,可指定flag(文件操做选项,如r+ 读写;w+ 读写,文件不存在则建立)及encoding属性 * callback 读取文件后的回调函数,参数默认第一个err,第二个data 数据 */ const fs = require("fs"); fs.readFile('./package.json',{flag:"r+",encoding:"utf8"},(err,data)=>{ if(err) throw err; console.log(data); })
// fs.writeFile(filename,data,[options],callback); /** * filename, 必选参数,文件名 * data, 写入的数据,能够字符或一个Buffer对象 * [options],flag,mode(权限),encoding * callback 读取文件后的回调函数,参数默认第一个err,第二个data 数据 */ const fs = require("fs"); const data="hello world"; const bf=Buffer.from(data); //buffer写入 fs.writeFile("./test.txt",bf,err=>{ if(err) throw err; console.log("写入成功"); }) //字符写入 fs.writeFile("./test.txt",data,err=>{ if(err) throw err; console.log("写入成功"); })
// fs.appendFile(filename,data,[options],callback); const fs = require("fs"); const data = " hello world"; const bf = Buffer.from(data); //buffer fs.appendFile("./test.txt", bf, err => { if (err) throw err; console.log("追加成功"); }) fs.appendFile("./test.txt", data, err => { if (err) throw err; console.log("追加成功"); })
打开文件,获取文件描述数组
// fs.open(filename, flags, [mode], callback); /** * filename, 必选参数,文件名 * flags, 操做标识,如"r",读方式打开 * [mode],权限,如777,表示任何用户读写可执行 * callback 打开文件后回调函数,参数默认第一个err,第二个fd为一个整数,表示打开文件返回的文件描述符,window中又称文件句柄 */ const fs = require("fs"); fs.open("./test.txt","r",0666,(err,fd)=>{ if(err) throw err; console.log(fd); //3 })
【0666】为【文件权限码】,也能够在【fs.constants】中输出缓存
//fs.read(fd, buffer, offset, length, position, callback); /** * fd, 使用fs.open打开成功后返回的文件描述符 * buffer, 一个Buffer对象,v8引擎分配的一段内存 * offset, 整数,向缓存区中写入时的初始位置,以字节为单位 * length, 整数,读取文件的长度 * position, 整数,读取文件初始位置;文件大小以字节为单位 * callback(err, bytesRead, buffer), 读取执行完成后回调函数,bytesRead实际读取字节数,被读取的缓存区对象 */ const fs = require("fs"); fs.open("./test.txt", "r", (err, fd) => { if (err) throw err; let bf = Buffer.alloc(255); fs.read(fd,bf,0,9,0,(err,bytesRead,buffer)=>{ if(err) throw err; console.log(bytesRead); console.log(buffer.toString()); }) })
//fs.write(fd, buffer, offset, length, position, callback); /** * fd, 使用fs.open打开成功后返回的文件描述符 * buffer, 一个Buffer对象,v8引擎分配的一段内存 * offset, 整数,从缓存区中读取时的初始位置,以字节为单位 * length, 整数,从缓存区中读取数据的字节数 * position, 整数,写入文件初始位置; * callback(err, written, buffer), 写入操做执行完成后回调函数,written实际写入字节数,buffer被读取的缓存区对象 */ const fs = require("fs"); fs.open("./test.txt", "w", (err, fd) => { if (err) throw err; let bf = Buffer.from(" 写入文件数据的内容"); fs.write(fd, bf, 0, bf.length, 0, (err, bytesWritten, buffer) => { if (err) throw err; console.log(bytesWritten); console.log(`写入的内容:${buffer.toString()}`); }) })
使用fs.write写入文件时,操做系统是将数据读到内存,再把数据写入到文件中,当数据读完时并不表明数据已经写完,由于有一部分还可能在内在缓冲区内。
所以可使用fs.fsync方法将内存中数据写入文件;--刷新内存缓冲区;app
//fs.fsync(fd, [callback]) /** * fd, 使用fs.open打开成功后返回的文件描述符 * [callback(err, written, buffer)], 写入操做执行完成后回调函数,written实际写入字节数,buffer被读取的缓存区对象 */ const fs = require("fs"); fs.open("./test.txt", "a+", (err, fd) => { if (err) throw err; let bf = Buffer.from(" I love Node"); fs.write(fd, bf, 0, bf.length, 0, (err, bytesWritten, buffer) => { if (err) throw err; fs.fsync(fd,(err)=>{}); fs.close(fd,err=>{}); }) })
//使用fs.readdir读取目录,重点其回调函数中files对象 //fs.readdir(path, callback); /** * path, 要读取目录的完整路径及目录名; * [callback(err, files)], 读完目录回调函数;err错误对象,files数组,存放读取到的目录中的全部文件名 */ const fs = require("fs"), path = require("path"); fs.readdir(__dirname + "/../11文件系统fs", (err, files) => { if (err) throw err; files.forEach(file => { let filePath = path.normalize(__dirname + '/' + file); fs.stat(filePath, (err, stats) => { if (stats.isFile()) { console.log(filePath + ' is: ' + 'file'); } if (stats.isDirectory()) { console.log(filePath + ' is: ' + 'dir'); } }) }) })
//fs.createReadStream(path, [options]) /** * path 文件路径 * [options] flags:指定文件操做,默认'r',读操做;encoding,指定读取流编码;autoClose, 是否读取完成后自动关闭,默认true;start指定文件开始读取位置;end指定文件开始读结束位置 */ const fs = require("fs"); const rs = fs.createReadStream("./package.json", { flags: "r" }); rs.on("open", fd => console.log('开始读取文件')); rs.on('data', data => { console.log(data.toString()); }) rs.on('end', function () { console.log('读取文件结束') }); rs.on('close', function () { console.log('文件关闭'); }); rs.on('error', function (err) { console.error(err); });
//fs.createWriteStream(path, [options]) /** * path 文件路径 * [options] flags:指定文件操做,默认'w',;encoding,指定读取流编码;start指定写入文件的位置 */ /* ws.write(chunk, [encoding], [callback]); * chunk, 能够为Buffer对象或一个字符串,要写入的数据 * [encoding], 编码 * [callback], 写入后回调 */ /* ws.end([chunk], [encoding], [callback]); * [chunk], 要写入的数据 * [encoding], 编码 * [callback], 写入后回调 */ const fs = require("fs"); const ws=fs.createWriteStream("./test.txt",{flags:"w"}) const bf=Buffer.from("I Love Node"); ws.on('open', function () { console.log('文件流开启') }); ws.on('close', function () { console.log('文件流关闭'); }); ws.on('error', function (err) { console.error(err); }); ws.write(bf,"utf8",(err,buffer)=>{ console.log('写入完成') }) ws.end(' Bye');
流复制文件就是建立一个读取流和一个写入流,将读取流中的流出的数据用写入流进行写入异步
//使用流复制文件 const fs = require("fs"); const rs = fs.createReadStream("./package.json"); const ws = fs.createWriteStream("./package1.json"); rs.on("data", data => { ws.write(data); }) ws.on('open', function (fd) { console.log('要写入的数据文件已经打开,文件描述符是: ' + fd); }); rs.on("end",()=>{ console.log('文件读取完成'); ws.end('完成',()=>{ console.log("文件写入完成"); }) })
关于WriteStream对象的write方法返回一个布尔类型,当缓存区中数据所有写满时,返回false;表示缓存区已经写满,并将当即输出到目标对象中。函数
一个例子测试返回值:测试
const fs = require("fs"); var ws = fs.createWriteStream(__dirname + '/test.txt',{flags:"w"}); for (var i = 0; i < 10000; i++) { var w_flag = ws.write(i.toString()); //当缓存区写满时,输出false console.log(w_flag); }
一个例子当缓存区数据所有输出时,触发事件ui
const fs = require("fs"); const rs = fs.createReadStream("./ABoy.mp3"); const ws = fs.createWriteStream("./ABoy1.mp3"); rs.on("data", data => { let t = ws.write(data); if(!t){ console.log(t); } }) ws.on("drain", () => { console.log('系统缓存区数据已经所有输出。') })
上面使用一个读取流额一个写入流进行了一次文件的复制,还有另一种方式就是在写入流和读取流之间创建一条管道,是读取流中的数据经过管道源源不断的流向写入流,实现文件的复制。
const fs = require("fs"); const rs = fs.createReadStream("./ABoy.mp3"); const ws = fs.createWriteStream("./ABoy1.mp3"); rs.pipe(ws); rs.on('data', function (data) { console.log('数据可读') }); rs.on('end', function () { console.log('文件读取完成'); }); ws.on("drain", () => { console.log('系统缓存区数据已经所有输出。') }); ws.on('open', function (fd) { console.log('要写入的数据文件已经打开,文件描述符是: ' + fd); });
CSDN 【Node文件系统fs模块】同步更新