nodejs fs模块

来源:互联网 发布:淘宝沙宣官方旗舰店 编辑:程序博客网 时间:2024/06/05 19:05

nodejs FileSystem 模块

nodejs 的文件模块 从读写两方面入手。

首先说明一下文件操作模式
‘r’ - 以读取模式打开文件。如果文件不存在则发生异常。
‘r+’ - 以读写模式打开文件。如果文件不存在则发生异常。
‘rs+’ - 以同步读写模式打开文件。命令操作系统绕过本地文件系统缓存。
这对 NFS 挂载模式下打开文件很有用,因为它可以让你跳过潜在的旧本地缓存。 它对 I/O 的性能有明显的影响,所以除非需要,否则不要使用此标志。
注意,这不会使 fs.open() 进入同步阻塞调用。 如果那是你想要的,则应该使用 fs.openSync()。
‘w’ - 以写入模式打开文件。文件会被创建(如果文件不存在)或截断(如果文件存在)。
‘wx’ - 类似 ‘w’,但如果 path 存在,则失败。
‘w+’ - 以读写模式打开文件。文件会被创建(如果文件不存在)或截断(如果文件存在)。
‘wx+’ - 类似 ‘w+’,但如果 path 存在,则失败。
‘a’ - 以追加模式打开文件。如果文件不存在,则会被创建。
‘ax’ - 类似于 ‘a’,但如果 path 存在,则失败。
‘a+’ - 以读取和追加模式打开文件。如果文件不存在,则会被创建。
‘ax+’ - 类似于 ‘a+’,但如果 path 存在,则失败

调用 fs模块

var fs = require("fs");

读文件

  1. readFile 读取文件函数
    该函数是异步读取文件内容
/** * 参数: filename , [options] , callback * filename: 必选参数,一定是文件的具体路径 * [options]: 可选参数 两种凡方式 第一种 不使用flag 则直接"utf8" ,否则格式如下 * callback : 读取文件的回调函数 第一个默认是err , 只有两个参数的时候才会将内容显示出来(data 参数可选) */fs.readFile(__dirname+'/log.txt',{flag:"r",encoding:"utf8"},function (err,data) {    //如果读取文件出错 则 err = true    if(err){        console.log("读取文件出错!");        console.error(err);    }else{        console.log("读取文件成功");        console.log(data);    }})

readFile同步调用函数为readFileSync(filename,[options]),该函数直接返回 file内容(buffer),如果指定了options编码格式 则返回的内容是字符串。
2. 读取打开的文件 fs.open /fs.read

windows下文字描述符如下:
O_RDONLY: 0,
O_WRONLY: 1,
O_RDWR: 2,
S_IFMT: 61440,
S_IFREG: 32768,
S_IFDIR: 16384,
S_IFCHR: 8192,
S_IFLNK: 40960,
O_CREAT: 256,
O_EXCL: 1024,
O_TRUNC: 512,
O_APPEND: 8,
F_OK: 0,
R_OK: 4,
W_OK: 2,
X_OK: 1

fs.open(filename,flags,[mode],callback)

/** * 先打开文件 然后再读取 open read 函数 * open(filename,flags,[mode],callback) * filename:完整的文件名(必选参数) * flags: 操作标识 r:以读方式打开,r+:以读写模式打开文件 * [modes],权限,777 表示任何用户读写可以执行 默认是0666 (只有文件已经存在才有效) * callback 打开文件之后回调函数 有两个参数 第一个默认err, 第二个为整数 表示打开文件返回的文字描述符 * * */fs.open(__dirname+'/log.txt',"r","0666",function (err,fd) {    if(err){        console.error(err);    }else{        console.log(fd);        console.log(fs.constants); //得到所有的文字描述符    }});

fs.read
函数参数
fs.read(fd,buffer,offset,length,position,callback);

/** * fs.read(fd,buffer,offset,length,position,callback); * fd:fs.open()返回的文件描述符 * buffer:数据将被分配的对象区域 ,由v8引擎分配的内存 * offset:向buffer开始写入的偏移量 以字节为单位 (buffer内存开始的位置) * length:指定要读取的文件长度 * position:指定从文件中哪个位置开始读取文件 , 默认是从文件其实位置开始。 (读取文件开始的位置) * callback:回调函数 (err,bytesRead,buffer) bytesRead 表示实际读取的字节数 buffer 表示被读取的对象 */fs.open(__dirname+"/log.txt","r","0666",function (err,fd) {    if(err){        console.error(err);    }else{        var buffer = new Buffer(255);        console.log(buffer.length);        //每个汉字的utf8编码是3个字节,英文的utf8编码是1个 下面的9 相当于只读取了3个汉字        fs.read(fd,buffer,0,9,0,function (err,bytesRead,buffer) {            if(err){                console.error(err);            }else{                console.log(bytesRead);                console.log(buffer.slice(0,bytesRead).toString());                fs.read(fd,buffer,0,9,null,function (err,bytesRead,buffer) {                    console.log(bytesRead);                    console.log(buffer.slice(0,bytesRead).toString());                })            }        })    }});

写文件

  1. fs.writeFile
    参数:fs.writeFile(filename,data,[options],callback)
/** * filename:完整文件路径 如果文件已存在则替换文件内容 ,若文件不存在则创建一个同名文件并追加内容 * data:anything,在这里我使用的是buffer  如果 data 是一个 buffer,则忽略 encoding 选项。它默认为 'utf8' * [options]:文件操作类型 读写 同步等等 还有文件的编码等 * callback:只err */fs.writeFile(__dirname+'/write.txt',wbuffer,{encoding:"utf8",flag:"w"},(err)=>{    if(err){        console.error(err);    }else{        console.log("write success ");    }})//追加文件fs.appendFile(__dirname+'/write.txt',wbuffer,{encoding:"utf8",flag:"a+"},(err)=>{    if(err){        console.error(err);    }else{        console.log("追加成功");    }})
  1. fs.write()
    参数fs.write(fd, buffer, offset, length, position, callback);
fs.open(__dirname+'/write.txt',"a+",(err,fd)=>{    if(err) {        console.error(err);    }else{        console.log("打开成功!");        fs.write(fd,wbuffer,0,12,0,(err,bytesWritten,buffer)=>{            if(err){                console.error(err);            }else{                console.log("写入成功");                console.log(bytesWritten); // 12                console.log(buffer.slice(0,bytesWritten).toString()); //写入文本                //刷新缓存区 fs.write写入文件时,操作系统是将数据读到内存,再将数据写到文件中,                //当数据读完并不代表数据已经写完,因为有一部分还可能在内存中的缓冲区中                //我们可以使用fs.fsync方法将内存中的数据写入文件  刷新内存缓冲区                fs.fsync(fd,(err)=>{ //可能不会执行                    if(err){                        console.error(err);                    }else{                        console.log("flush success");                    }                });                fs.close(fd,(err)=>{if(err){console.error(err)}});            }        })    }});

目录

  1. 创建目录

    fs.mkdir(path,[mode],callback);

 /** * path:被创建的目录名  完整目录路径 * [mode]:创建的目录权限 默认是 777 可读可写 * callback */fs.mkdir(__dirname+'/fsDir',777,(err)=>{   if(err){       console.error(err);   }else{       console.log("创建目录成功");   }}); 
  1. 读取目录
    fs.readdir(path,options,callback)
    fs.stat() 用于检查一个文件是否存在 ,返回的 stat是 fs.Stat一个对象实例,提供如:isFile, isDirectory,isBlockDevice等方法及size,ctime,mtime等属性
/** *  * path:目录路径 * options: encoding 默认utf8 * callback : err , files:返回该目录下所有的文件包括文件夹 但是不包括以.. . 开头的文件 */var path = require('path');fs.readdir(__dirname+'/fsDir/',(err,files)=>{    if(err){        console.error(err);    }else{        console.log("读取目录成功");        files.forEach(function (file) {           console.log(__dirname+"/fsDir/"+file); // D:\git\node_demo/fsDir/123           //得到文件的路径 使用path.mormalize()规范化路径的分隔符           var filePath = path.normalize(__dirname+"/fsDir/"+file);//D:\git\node_demo\fsDir\123is:dir           //fs.stat() 检查一个文件是否存在      //fs.access           // stats:           fs.stat(filePath,function (err,stats) {              //stats确定               if(stats.isFile()){                   console.log(filePath+'is:file');               }               if(stats.isDirectory()){                   console.log(filePath+'is:dir');               }           });        });    }});
  1. 目录是否存在
    fs.exist(path,callback);
//exists=true/falsefs.exists(__dirname+'/fsDir',function (exists) {   if(exists){       console.log("目录存在");   }else{       console.log("目录不存在");   }});

监视

  • 文件监视
    监视文件是否被修改
    fs.watchFile(filename,[options],listener);
/** * fs.watchFile(filename,[options],listener) * filename:文件名 完整路径 * options: 可省略 如果不省略就应该是一个对象{},这个对象包含两个属性: *    persistent:表示当文件正再被监视时,进程是否应该继续运行 *    interval: 表示指定文件夹应该每隔多少毫秒被轮询一次 *    默认值:persistent:true,interval:5007; *listener:类型为function 指定文件发生变化时回调 有两个参数 *    curr:fs.Stat 对象 表示修改后对象 *    prev: fs.Stat 对象 表示修改前对象 */fs.watchFile(__dirname+'/fsDir/123.txt',{persistent:true,interval:2000},(curr, prev)=>{    if(Date.parse(prev.ctime) === 0){        console.log("文件被创建");    }else if(Date.parse(curr.ctime) ===0){        console.log("文件被删除")    }else if(Date.parse(curr.mtime) != Date.parse(prev.mtime)) {        console.log('文件有修改');    }});fs.watchFile(__dirname + '/fsDir/123.txt',{persistent:true,interval:2000},function (curr, prev) {    console.log("文件有修改");})

取消监视文件

//取消对文件进行监视//fs.unwatchFile(filename, [listener]);/** * filename, 完整路径及文件名; * [listener], 要取消的监听器事件,如果不指定,则取消所有监听处理事件 */var listener = function (curr, prev) {  console.log('取消监视函数')}fs.unwatchFile(__dirname + '/fsDir/123.txt', listener);

流的操作

  • 创建读取流
//fs.createReadStream(path, [options])/** * path 文件路径 * [options] flags:指定文件操作,默认'r',读操作;encoding,指定读取流编码;autoClose, 是否读取完成后自动关闭,默认true;start指定文件开始读取位置;end指定文件开始读结束位置 */var rs = fs.createReadStream(__dirname + '/test.txt', {start: 0, end: 2});  //open是ReadStream对象中表示文件打开时事件,rs.on('open', function (fd) {  console.log('开始读取文件');});rs.on('data', function (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);});//暂停和回复文件读取;rs.on('open', function () {  console.log('开始读取文件');});rs.pause();rs.on('data', function (data) {  console.log(data.toString());});setTimeout(function () {  rs.resume();}, 2000);
  • 创建写入流
//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],  写入后回调 */var ws = fs.createWriteStream(__dirname + '/test.txt', {start: 0});var buffer = new Buffer('我也喜欢你');ws.write(buffer, 'utf8', function (err, buffer) {  console.log(arguments);  console.log('写入完成,回调函数没有参数')});//最后再写入的内容ws.end('再见');//使用流完成复制文件操作var rs = fs.createReadStream(__dirname + '/test.txt')var ws = fs.createWriteStream(__dirname + '/test/test.txt');rs.on('data', function (data) {  ws.write(data)});ws.on('open', function (fd) {  console.log('要写入的数据文件已经打开,文件描述符是: ' + fd);});rs.on('end', function () {  console.log('文件读取完成');  ws.end('完成', function () {    console.log('文件全部写入完成')  });});//关于WriteStream对象的write方法返回一个布尔类型,当缓存区中数据全部写满时,返回false;//表示缓存区写满,并将立即输出到目标对象中//第一个例子var ws = fs.createWriteStream(__dirname + '/test/test.txt');for (var i = 0; i < 10000; i++) {  var w_flag = ws.write(i.toString());  //当缓存区写满时,输出false  console.log(w_flag);}//第二个例子var ws = fs.createWriteStream(__dirname + '/test/untiyou.mp3');var rs = fs.createReadStream(__dirname + '/test/Until You.mp3');rs.on('data', function (data) {  var flag = ws.write(data);  console.log(flag);});//系统缓存区数据已经全部输出触发drain事件ws.on('drain', function () {  console.log('系统缓存区数据已经全部输出。')});
  • 管道pipe实现流读写
//rs.pipe(destination, [options]);/** * destination 必须一个可写入流数据对象 * [opations] end 默认为true,表示读取完成立即关闭文件; */var rs = fs.createReadStream(__dirname + '/test/Until You.mp3');var ws = fs.createWriteStream(__dirname + '/test/untiyou.mp3');rs.pipe(ws);rs.on('data', function (data) {  console.log('数据可读')});rs.on('end', function () {  console.log('文件读取完成');  //ws.end('再见')});

最后 本文是参见 明明三省的博客,简述了自己觉得重要的部分。

0 0