js文件操作详解,js操作详解
分类:新闻中心

写文件

node js文件操作是哪个模

内置文件操作模块是fs
require('fs')  

21、管道pipe实现流读写

//rs.pipe(destination, [options]);

/**

 * destination 必须一个可写入流数据对象

 * [opations] end 默认为true,表示读取完成立即关闭文件;

 */

 

1.        var rs = fs.createReadStream(__dirname + '/test/Until You.mp3');

2.        var ws = fs.createWriteStream(__dirname + '/test/untiyou.mp3');

3.        rs.pipe(ws);

4.         

5.        rs.on('data', function (data) {

6.            console.log('数据可读')

7.        });

8.         

9.        rs.on('end', function () {

10.         console.log('文件读取完成');

11.         //ws.end('再见')

12.     });

 

//---------------------路径操作-------------------------

参数

参数使用说明如下:

  • file - 文件名或文件描述符。

  • data - 要写入文件的数据,可以是 String(字符串) 或 Buffer(流) 对象。

  • options - 该参数是一个对象,包含 {encoding, mode, flag}。默认编码为 utf8, 模式为 0666 , flag 为 'w'

  • callback - 回调函数,回调函数只包含错误信息参数(err),在写入失败时返回。

                // => ../../impl/bbb

nodejs中,各种普通函数的文档说明在什地方找?比如字符串处理,类似asubstring()这样的?

node.js是用的google v8作为javascript的引擎,所以只要是chrome浏览器里支持的javascript的object和函数,node.js里都有。node的网站上的api只是node自己新添的东西。所以你可以看在mozilla的网站上的javascript reference就行了。developer.mozilla.org/en/docs/JavaScript/Reference  

Node有一组数据流API,可以像处理网络流那样处理文件,用起来很方便,但是它只允许顺序处理文件,不...

3、以追加方式写文件

// fs.appendFile(filename,data,[options],callback);

1.        fs.appendFile(__dirname + '/test.txt', '使用fs.appendFile追加文件内容', function () {

2.            console.log('追加内容完成');

3.        });

 

 

一旦进程启动完毕,就能使用这几个文件描述符了,它们其实并不存在对应的物理文件。你不能读写某个随机位置的数据,(译者注:原文是You can write to and read from specific positions within the file.根据上下文,作者可能少写了个“not”),只能像操作网络数据流那样顺序的读取和输出,已写入的数据就不能再修改了。

Node.js文件操作详解,node.js操作详解

Node有一组数据流API,可以像处理网络流那样处理文件,用起来很方便,但是它只允许顺序处理文件,不能随机读写文件。因此,需要使用一些更底层的文件系统操作。

本章覆盖了文件处理的基础知识,包括如何打开文件,读取文件某一部分,写数据,以及关闭文件。

Node的很多文件API几乎是UNIX(POSIX)中对应文件API 的翻版,比如使用文件描述符的方式,就像UNIX里一样,文件描述符在Node里也是一个整型数字,代表一个实体在进程文件描述符表里的索引。

有3个特殊的文件描述符——1,2和3。他们分别代表标准输入,标准输出和标准错误文件描述符。标准输入,顾名思义,是个只读流,进程用它来从控制台或者进程通道读取数据。标准输出和标准错误是仅用来输出数据的文件描述符,他们经常被用来向控制台,其它进程或文件输出数据。标准错误负责错误信息输出,而标准输出负责普通的进程输出。

一旦进程启动完毕,就能使用这几个文件描述符了,它们其实并不存在对应的物理文件。你不能读写某个随机位置的数据,(译者注:原文是You can write to and read from specific positions within the file.根据上下文,作者可能少写了个“not”),只能像操作网络数据流那样顺序的读取和输出,已写入的数据就不能再修改了。

普通文件不受这种限制,比如Node里,你即可以创建只能向尾部追加数据的文件,还可以创建读写随机位置的文件。

几乎所有跟文件相关的操作都会涉及到处理文件路径,本章先会将介绍这些工具函数,然后再深入讲解文件读写和数据操作

处理文件路径

文件路径分为相对路径和绝对路径两种,用它们来表示具体的文件。你可以合并文件路径,可以提取文件名信息,甚至可以检测文件是否存在。

Node里,可以用字符串来操处理文件路径,但是那样会使问题变复杂,比如你要连接路径的不同部分,有些部分以 “/”结尾有些却没有,而且路径分割符在不同操作系统里也可能会不一样,所以,当你连接它们时,代码就会非常罗嗦和麻烦。

幸运的是,Node有个叫path的模块,可以帮你标准化,连接,解析路径,从绝对路径转换到相对路径,从路径中提取各部分信息,检测文件是否存在。总的来说,path模块其实只是些字符串处理,而且也不会到文件系统去做验证(path.exists函数例外)。

路径的标准化

在存储或使用路径之前将它们标准化通常是个好主意。比如,由用户输入或者配置文件获得的文件路径,或者由两个或多个路径连接起来的路径,一般都应该被标准化。可以用path模块的normalize函数来标准化一个路径,而且它还能处理“..”,“.”“//”。比如:

复制代码 代码如下:

var path = require('path');

path.normalize('/foo/bar//baz/asdf/quux/..');

// => '/foo/bar/baz/asdf'

连接路径

使用path.join()函数,可以连接任意多个路径字符串,只用把所有路径字符串依次传递给join()函数就可以:

复制代码 代码如下:

                   var path = require('path');

                   path.join('/foo', 'bar', 'baz/asdf', 'quux', '..');

                   // => '/foo/bar/baz/asdf'

如你所见,path.join()内部会自动将路径标准化。

解析路径

用path.resolve()可以把多个路径解析为一个绝对路径。它的功能就像对这些路径挨个不断进行“cd”操作,和cd命令的参数不同,这些路径可以是文件,并且它们不必真实存在——path.resolve()方法不会去访问底层文件系统来确定路径是否存在,它只是一些字符串操作。

比如:

复制代码 代码如下:

                   var path = require('path');

                   path.resolve('/foo/bar', './baz');

                   // => /foo/bar/baz

                   path.resolve('/foo/bar', '/tmp/file/');

                   // => /tmp/file

如果解析结果不是绝对路径,path.resolve()会把当前工作目录作为路径附加到解析结果前面,比如:

复制代码 代码如下:

        path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif');
        // 如果当前工作目录是/home/myself/node, 将返回
        // => /home/myself/node/wwwroot/static_files/gif/image.gif'

计算两个绝对路径的相对路径

path.relative()可以告诉你如果从一个绝对地址跳转到另外一个绝对地址,比如:

复制代码 代码如下:

                var path = require('path');

                path.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb');

                // => ../../impl/bbb

从路径提取数据

以路径“/foo/bar/myfile.txt”为例,如果你想获取父目录(/foo/bar)的所有内容,或者读取同级目录的其它文件,为此,你必须用path.dirname(filePath)获得文件路径的目录部分,比如:

复制代码 代码如下:

                   var path = require('path');

                   path.dirname('/foo/bar/baz/asdf/quux.txt');

                   // => /foo/bar/baz/asdf

 或者,你想从文件路径里得到文件名,也就是文件路径的最后那一部分,可以使用path.basename函数:  

复制代码 代码如下:

                    var path = require('path');

                   path.basename('/foo/bar/baz/asdf/quux.html')

                   // => quux.html  

文件路径里可能还包含文件扩展名,通常是文件名中最后一个“.”字符之后的那部分字符串。

path.basename还可以接受一个扩展名字符串作为第二个参数,这样返回的文件名就会自动去掉扩展名,仅仅返回文件的名称部分:

复制代码 代码如下:

                   var path = require('path');

                   path.basename('/foo/bar/baz/asdf/quux.html', '.html');

                   // => quux

 要想这么做你首先还得知道文件的扩展名,可以用path.extname()来获取扩展名:

复制代码 代码如下:

                   var path = require('path');

                   path.extname('/a/b/index.html');

                   // => '.html'

                   path.extname('/a/b.c/index');

                   // => ''

                   path.extname('/a/b.c/.');

                   // => ''

                   path.extname('/a/b.c/d.');

                   // => '.'

检查路径是否存在

目前为止,前面涉及到的路径处理操作都跟底层文件系统无关,只是一些字符串操作。然而,有些时候你需要判断一个文件路径是否存在,比如,你有时候需要判断文件或目录是否存在,如果不存在的话才创建它,可以用path.exsits():

复制代码 代码如下:

                   var path = require('path');

                   path.exists('/etc/passwd', function(exists) {

                            console.log('exists:', exists);

                            // => true

                   });

                   path.exists('/does_not_exist', function(exists) {

                            console.log('exists:', exists);

                            // => false

                   });

注意:从Node0.8版本开始,exists从path模块移到了fs模块,变成了fs.exists,除了命名空间不同,其它都没变:

复制代码 代码如下:

                   var fs = require('fs');

                   fs.exists('/does_not_exist', function(exists) {

                            console.log('exists:', exists);

                            // => false

                   });

path.exists()是个I/O操作,因为它是异步的,因此需要一个回调函数,当I/O操作返回后调用这个回调函数,并把结果传递给它。你还可以使用它的同步版本path.existsSync(),功能完全一样,只是它不会调用回调函数,而是直接返回结果:

复制代码 代码如下:

                  var path = require('path');

                 path.existsSync('/etc/passwd');

                 // => true

fs模块介绍

fs模块包含所有文件查询和处理的相关函数,用这些函数,可以查询文件信息,读写和关闭文件。这样导入fs模块:

复制代码 代码如下:

         var fs = require(‘fs')

查询文件信息

有时你可能需要知道文件的大小,创建日期或者权限等文件信息,可以使用fs.stath函数来查询文件或目录的元信息:

复制代码 代码如下:

                   var fs = require('fs');

                  fs.stat('/etc/passwd', function(err, stats) {

                                    if (err) { throw err;}

                                    console.log(stats);

                  });

这块代码片断会有类似下面的输出

复制代码 代码如下:

 { dev: 234881026,

ino: 95028917,

mode: 33188,

nlink: 1,

uid: 0,

gid: 0,

rdev: 0,

size: 5086,

blksize: 4096,

blocks: 0,

atime: Fri, 18 Nov 2011 22:44:47 GMT,

mtime: Thu, 08 Sep 2011 23:50:04 GMT,

ctime: Thu, 08 Sep 2011 23:50:04 GMT }

1.fs.stat()调用会将一个stats类的实例作为参数传递给它的回调函数,可以像下面这样使用stats实例:

2.stats.isFile() —— 如果是个标准文件,而不是目录,socket,符号链接或者设备,则返回true,否则false
3.stats.isDiretory() —— 如果是目录则返回tue,否则false
4.stats.isBlockDevice() —— 如果是块设备则返回true,在大多数UNIX系统中块设备通常都在/dev目录下
5.stats.isChracterDevice() —— 如果是字符设备返回true
6.stats.isSymbolickLink() —— 如果是文件链接返回true
7.stats.isFifo() —— 如果是个FIFO(UNIX命名管道的一个特殊类型)返回true
8.stats.isSocket() —— 如果是个UNIX socket(TODO:googe it)

打开文件

在读取或处理文件之前,必须先使用fs.open函数打开文件,然后你提供的回调函数会被调用,并得到这个文件的描述符,稍后你可以用这个文件描述符来读写这个已经打开的文件:

复制代码 代码如下:

                   var fs = require('fs');

                   fs.open('/path/to/file', 'r', function(err, fd) {

                        // got fd file descriptor

                   });

fs.open的第一个参数是文件路径,第二个参数是一些用来指示以什么模式打开文件的标记,这些标记可以是r,r+,w,w+,a或者a+。下面是这些标记的说明(来自UNIX文档的fopen页)

1.r —— 以只读方式打开文件,数据流的初始位置在文件开始
2.r+ —— 以可读写方式打开文件,数据流的初始位置在文件开始
3.w ——如果文件存在,则将文件长度清0,即该文件内容会丢失。如果不存在,则尝试创建它。数据流的初始位置在文件开始
4.w+ —— 以可读写方式打开文件,如果文件不存在,则尝试创建它,如果文件存在,则将文件长度清0,即该文件内容会丢失。数据流的初始位置在文件开始
5.a —— 以只写方式打开文件,如果文件不存在,则尝试创建它,数据流的初始位置在文件末尾,随后的每次写操作都会将数据追加到文件后面。
6.a+ ——以可读写方式打开文件,如果文件不存在,则尝试创建它,数据流的初始位置在文件末尾,随后的每次写操作都会将数据追加到文件后面。

读文件

一旦打开了文件,就可以开始读取文件内容,但是在开始之前,你得先创建一个缓冲区(buffer)来放置这些数据。这个缓冲区对象将会以参数形式传递给fs.read函数,并被fs.read填充上数据。

复制代码 代码如下:

var fs = require('fs');

fs.open('./my_file.txt', 'r', function opened(err, fd) {

if (err) { throw err }

var readBuffer = new Buffer(1024),

bufferOffset = 0,

bufferLength = readBuffer.length,

filePosition = 100;

fs.read(fd,

         readBuffer,

         bufferOffset,

         bufferLength,

         filePosition,

         function read(err, readBytes) {

                   if (err) { throw err; }

                   console.log('just read ' + readBytes + ' bytes');

                   if (readBytes > 0) {

                            console.log(readBuffer.slice(0, readBytes));

                   }

});

});

上面代码尝试打开一个文件,当成功打开后(调用opened函数),开始请求从文件流第100个字节开始读取随后1024个字节的数据(第11行)。

fs.read()的最后一个参数是个回调函数(第16行),当下面三种情况发生时,它会被调用:

1.有错误发生
2.成功读取了数据
3.没有数据可读

如果有错误发生,第一个参数(err)会为回调函数提供一个包含错误信息的对象,否则这个参数为null。如果成功读取了数据,第二个参数(readBytes)会指明被读到缓冲区里数据的大小,如果值是0,则表示到达了文件末尾。

注意:一旦把缓冲区对象传递给fs.open(),缓冲对象的控制权就转移给给了read命令,只有当回调函数被调用,缓冲区对象的控制权才会回到你手里。因此在这之前,不要读写或者让其它函数调用使用这个缓冲区对象;否则,你可能会读到不完整的数据,更糟的情况是,你可能会并发地往这个缓冲区对象里写数据。

写文件

通过传递给fs.write()传递一个包含数据的缓冲对象,来往一个已打开的文件里写数据:

复制代码 代码如下:

var fs = require('fs');

fs.open('./my_file.txt', 'a', function opened(err, fd) {

    if (err) { throw err; }

    var writeBuffer = new Buffer('writing this string'),

    bufferPosition = 0,

    bufferLength = writeBuffer.length, filePosition = null;

    fs.write( fd,

        writeBuffer,

        bufferPosition,

        bufferLength,

        filePosition,

        function wrote(err, written) {

           if (err) { throw err; }

           console.log('wrote ' + written + ' bytes');

        });

});

这个例子里,第2(译者注:原文为3)行代码尝试用追加模式(a)打开一个文件,然后第7行代码(译者注:原文为9)向文件写入数据。缓冲区对象需要附带几个信息一起做为参数:

1.缓冲区的数据
2.待写数据从缓冲区的什么位置开始
3.待写数据的长度
4.数据写到文件的哪个位置
5.当操作结束后被调用的回调函数wrote

这个例子里,filePostion参数为null,也就是说write函数将会把数据写到文件指针当前所在的位置,因为是以追加模式打开的文件,因此文件指针在文件末尾。

跟read操作一样,千万不要在fs.write执行过程中使用哪个传入的缓冲区对象,一旦fs.write开始执行它就获得了那个缓冲区对象的控制权。你只能等到回调函数被调用后才能再重新使用它。

关闭文件

你可能注意到了,到目前为止,本章的所有例子都没有关闭文件的代码。因为它们只是些仅使用一次而且又小又简单的例子,当Node进程结束时,操作系统会确保关闭所有文件。

但是,在实际的应用程序中,一旦打开一个文件你要确保最终关闭它。要做到这一点,你需要追踪所有那些已打开的文件描述符,然后在不再使用它们的时候调用fs.close(fd[,callback])来最终关闭它们。如果你不仔细的话,很容易就会遗漏某个文件描述符。下面的例子提供了一个叫openAndWriteToSystemLog的函数,展示了如何小心的关闭文件:

复制代码 代码如下:

var fs = require('fs');
function openAndWriteToSystemLog(writeBuffer, callback){
    fs.open('./my_file', 'a', function opened(err, fd) {
        if (err) { return callback(err); }
        function notifyError(err) {
            fs.close(fd, function() {
                callback(err);
            });
        }
        var bufferOffset = 0,
        bufferLength = writeBuffer.length,
        filePosition = null;
        fs.write( fd, writeBuffer, bufferOffset, bufferLength, filePosition,
            function wrote(err, written) {
                if (err) { return notifyError(err); }
                fs.close(fd, function() {
                    callback(err);
                });
            }
        );
    });
}
openAndWriteToSystemLog(
    new Buffer('writing this string'),
    function done(err) {
        if (err) {
            console.log("error while opening and writing:", err.message);
            return;
        }
        console.log('All done with no errors');
    }
);

  在这儿,提供了一个叫openAndWriteToSystemLog的函数,它接受一个包含待写数据的缓冲区对象,以及一个操作完成或者出错后被调用的回调函数,如果有错误发生,回调函数的第一个参数会包含这个错误对象。

注意那个内部函数notifyError,它会关闭文件,并报告发生的错误。

注意:到此为止,你知道了如何使用底层的原子操作来打开,读,写和关闭文件。然而,Node还有一组更高级的构造函数,允许你用更简单的方式来处理文件。

比如,你想用一种安全的方式,让两个或者多个write操作并发的往一个文件里追加数据,这时你可以使用WriteStream。

还有,如果你想读取一个文件的某个区域,可以考虑使用ReadStream。这两种用例会在第九章“数据的读,写流”里介绍。

小结

当你使用文件时,多数情况下都需要处理和提取文件路径信息,通过使用path模块你可以连接路径,标准化路径,计算路径的差别,以及将相对路径转化成绝对路径。你可以提取指定文件路径的扩展名,文件名,目录等路径组件。

Node在fs模块里提供了一套底层API来访问文件系统,底层API使用文件描述符来操作文件。你可以用fs.open打开文件,用fs.write写文件,用fs.read读文件,并用fs.close关闭文件。

当有错误发生时,你应该总是使用正确的错误处理逻辑来关闭文件——以确保在调用返回前关闭那些已打开的文件描述符。

21、管道pipe实现流读写... 18

语法

以下为创建目录的语法格式:

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

var fs = require('fs');

//公共引用

语法

以下为通过异步模式获取文件信息的语法格式:

fs.stat(path, callback)

文件路径分为相对路径和绝对路径两种,用它们来表示具体的文件。你可以合并文件路径,可以提取文件名信息,甚至可以检测文件是否存在。

23、路径结合、合并,路径最后不会带目录分隔符... 19

实例

接下来我们创建 file.js 文件,代码如下所示:

var fs = require("fs");

console.log("准备写入文件");
fs.writeFile('input.txt', '我是通过写入的文件内容!',  function(err) {
   if (err) {
       return console.error(err);
   }
   console.log("数据写入成功!");
   console.log("--------我是分割线-------------")
   console.log("读取写入的数据!");
   fs.readFile('input.txt', function (err, data) {
      if (err) {
         return console.error(err);
      }
      console.log("异步读取文件数据: " + data.toString());
   });
});

以上代码执行结果如下:

$ node file.js 
准备写入文件
数据写入成功!
--------我是分割线-------------
读取写入的数据!
异步读取文件数据: 我是通过写入的文件内容

Node在fs模块里提供了一套底层API来访问文件系统,底层API使用文件描述符来操作文件。你可以用fs.open打开文件,用fs.write写文件,用fs.read读文件,并用fs.close关闭文件。

1、读取文件readFile函数... 1

 

                   console.log('just read ' + readBytes + ' bytes');

Node.js文件系统、路径的操作函数... 1

 

                   var path = require('path');

28、path.extname(path). 21

删除文件

读文件

参考:... 21

 

bufferOffset = 0,

8、创建目录;

//使用fs.mkdir创建目录

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

/**

 * path, 被创建目录的完整路径及目录名;

 * [mode], 目录权限,默认0777

 * [callback(err)], 创建完目录回调函数,err错误对象

 */

1.        fs.mkdir(__dirname + '/fsDir', function (err) {

2.            if(err)

3.                throw err;

4.         

5.            console.log('创建目录成功')

6.        });

 

语法

以下为删除目录的语法格式:

fs.rmdir(path, callback)

一旦打开了文件,就可以开始读取文件内容,但是在开始之前,你得先创建一个缓冲区(buffer)来放置这些数据。这个缓冲区对象将会以参数形式传递给fs.read函数,并被fs.read填充上数据。

14、移动/重命名文件或目录

//fs.rename(oldPath, newPath, callback);

/**

 * oldPath, 原目录/文件的完整路径及名;

 * newPath, 新目录/文件的完整路径及名;如果新路径与原路径相同,而只文件名不同,则是重命名

 * [callback(err)], 操作完成回调函数;err操作失败对象

 */

 

1.        fs.rename(__dirname + '/test', __dirname + '/fsDir', function (err) {

2.            if(err) {

3.                console.error(err);

4.                return;

5.            }

6.            console.log('重命名成功')

7.        });

 

如你所见,path.join()内部会自动将路径标准化。

24、获取绝对路径

//path.resolve(path1, [path2]..[pathn]);

//以应用程序为起点,根据参数字符串解析出一个绝对路径

/**

 * path 必须至少一个路径字符串值

 * [pathn] 可选路径字符串

 */

1.        var myPath = path.resolve('path1', 'path2', 'a/b\c/');

2.        console.log(myPath);//E:workspaceNodeJSpath1path2abc

 

Node.js 提供一组类似 UNIX(POSIX)标准的文件操作API。 Node 导入文件系统模块(fs)语法如下所示:

比如,你想用一种安全的方式,让两个或者多个write操作并发的往一个文件里追加数据,这时你可以使用WriteStream。

参考:

《Node.js权威指南》之在Node.js中操作文件系统

参数

参数使用说明如下:

  • fd - 通过 fs.open() 方法返回的文件描述符。

  • len - 文件内容截取的长度。

  • callback - 回调函数,没有参数。

    var fs = require("fs"); var buf = new Buffer(1024);

    console.log("准备打开文件!"); fs.open('input.txt', 'r+', function(err, fd) { if (err) {

       return console.error(err);
    

    } console.log("文件打开成功!"); console.log("截取10字节后的文件内容。");

    // 截取文件 fs.ftruncate(fd, 10, function(err){

      if (err){
         console.log(err);
      } 
      console.log("文件截取成功。");
      console.log("读取相同的文件"); 
      fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
         if (err){
            console.log(err);
         }
    
         // 仅输出读取的字节
         if(bytes > 0){
            console.log(buf.slice(0, bytes).toString());
         }
    
         // 关闭文件
         fs.close(fd, function(err){
            if (err){
               console.log(err);
            } 
            console.log("文件关闭成功!");
         });
      });
    

    }); });

以上代码执行结果如下:

$ node file.js 
准备打开文件!
文件打开成功!
截取10字节后的文件内容。
文件截取成功。
读取相同的文件
site:www.r
文件关闭成功

Node里,可以用字符串来操处理文件路径,但是那样会使问题变复杂,比如你要连接路径的不同部分,有些部分以 “/”结尾有些却没有,而且路径分割符在不同操作系统里也可能会不一样,所以,当你连接它们时,代码就会非常罗嗦和麻烦。

22、路径解析,得到规范化的路径格式

//对window系统,目录分隔为'', 对于UNIX系统,分隔符为'/',针对'..'返回上一级;/与\都被统一转换

//path.normalize(p);

 

1.        var myPath = path.normalize(__dirname + '/test/a//b//../c/utilyou.mp3');

2.        console.log(myPath); //windows: E:workspaceNodeJSappfstestacutilyou.mp3

 

语法

以下为读取目录的语法格式:

fs.readdir(path, callback)

                   var fs = require('fs');

25、获取相对路径... 20

 

                   // => /foo/bar/baz

13、修改文件或目录的操作权限... 10

实例

接下来我们创建 file.js 文件,代码如下所示:

var fs = require("fs");

console.log("查看 /tmp 目录");
fs.readdir("/tmp/",function(err, files){
   if (err) {
       return console.error(err);
   }
   files.forEach( function (file){
       console.log( file );
   });
});

以上代码执行结果如下:

$ node file.js 
查看 /tmp 目录
input.out
output.out
test
test.txt

        bufferLength,

Node.js文件系统、路径的操作函数

参数

参数使用说明如下:

  • path - 文件路径。

  • callback - 回调函数,带有两个参数如:(err, stats), stats 是 fs.Stats 对象。

fs.stat(path)执行后,会将stats类的实例返回给其回调函数。可以通过stats类中的提供方法判断文件的相关属性。例如判断是否为文件:

var fs = require('fs');

fs.stat('/Users/liuht/code/itbilu/demo/fs.js', function (err, stats) {
    console.log(stats.isFile());         //true
})

stats类中的方法有:

方法 描述
stats.isFile() 如果是文件返回 true,否则返回 false。
stats.isDirectory() 如果是目录返回 true,否则返回 false。
stats.isBlockDevice() 如果是块设备返回 true,否则返回 false。
stats.isCharacterDevice() 如果是字符设备返回 true,否则返回 false。
stats.isSymbolicLink() 如果是软链接返回 true,否则返回 false。
stats.isFIFO() 如果是FIFO,返回true,否则返回 false。FIFO是UNIX中的一种特殊类型的命令管道。
stats.isSocket() 如果是 Socket 返回 true,否则返回 false。

使用path.join()函数,可以连接任意多个路径字符串,只用把所有路径字符串依次传递给join()函数就可以:

30、path.delimiter属性

返回操作系统中目录分隔符,如window是';', Unix中是':'

 

 

参数

参数使用说明如下:

  • path - 文件路径。

  • callback - 回调函数,回调函数带有两个参数err, files,err 为错误信息,files 为 目录下的文件数组列表。

 要想这么做你首先还得知道文件的扩展名,可以用path.extname()来获取扩展名:

7、刷新缓存区;6

参数

参数使用说明如下:

  • path - 文件路径。

  • callback - 回调函数,没有参数。

    var fs = require("fs");

    console.log("准备删除文件!"); fs.unlink('input.txt', function(err) { if (err) {

       return console.error(err);
    

    } console.log("文件删除成功!"); });

以上代码执行结果如下:

node file.js 
准备删除文件!
文件删除成功!

                   var path = require('path');

6、写文件,将缓冲区内数据写入使用fs.open打开的文件

//fs.write(fd, buffer, offset, length, position, callback);

/**

 * fd, 使用fs.open打开成功后返回的文件描述符

 * buffer, 一个Buffer对象,v8引擎分配的一段内存

 * offset, 整数,从缓存区中读取时的初始位置,以字节为单位

 * length, 整数,从缓存区中读取数据的字节数

 * position, 整数,写入文件初始位置;

 * callback(err, written, buffer), 写入操作执行完成后回调函数,written实际写入字节数,buffer被读取的缓存区对象

 */

 

1.        fs.open(__dirname + '/test.txt', 'a', function (err, fd) {

2.            if(err) {

3.                console.error(err);

4.                return;

5.            } else {

6.                var buffer = new Buffer('写入文件数据内容');

7.                //写入'入文件'三个字

8.                fs.write(fd, buffer, 3, 9, 12, function (err, written, buffer) {

9.                    if(err) {

10.                     console.log('写入文件失败');

11.                     console.error(err);

12.                     return;

13.                 } else {

14.                     console.log(buffer.toString());

15.                     fs.write(fd, buffer, 12, 9, null, function (err, written, buffer) {

16.                         console.log(buffer.toString());

17.                     })

18.                 }

19.             });

20.         }

21.     });

 

语法

以下为异步模式下读取文件的语法格式:

fs.read(fd, buffer, offset, length, position, callback)

该方法使用了文件描述符来读取文件。

从路径提取数据

12、修改文件访问时间与修改时间

//fs.utimes(path, atime, mtime, callback);

/**

 * path, 要查看目录/文件的完整路径及名;

 * atime, 新的访问时间

 * ctime, 新的修改时间

 * [callback(err)], 操作完成回调函数;err操作失败对象

 */

 

1.        fs.utimes(__dirname + '/test.txt', new Date(), new Date(), function (err) {

2.            if(err) {

3.                console.error(err);

4.                return;

5.            }

6.            fs.stat(__dirname + '/test.txt', function (err, stat) {

7.                console.log('访问时间: ' + stat.atime.toString() + '; n修改时间:' + stat.mtime);

8.                console.log(stat.mode);

9.            })

10.     });

 

 

您可能感兴趣的文章:

  • Nodejs获取网络数据并生成Excel表格
  • nodejs导出excel的方法
  • 详解使用Node.js 将txt文件转为Excel文件
  • Node.js利用js-xlsx处理Excel文件的方法详解
  • Node.js实现Excel转JSON
  • nodejs文件操作模块FS(File System)常用函数简明总结
  • 在Node.js中实现文件复制的方法和实例
  • node.js实现逐行读取文件内容的代码
  • nodejs简单读写excel内容的方法示例

18、文件流

/*

 * 流,在应用程序中表示一组有序的、有起点有终点的字节数据的传输手段;

 * Node.js中实现了stream.Readable/stream.Writeable接口的对象进行流数据读写;以上接口都继承自EventEmitter类,因此在读/写流不同状态时,触发不同事件;

 * 关于流读取:Node.js不断将文件一小块内容读入缓冲区,再从缓冲区中读取内容;

 * 关于流写入:Node.js不断将流数据写入内在缓冲区,待缓冲区满后再将缓冲区写入到文件中;重复上面操作直到要写入内容写写完;

 * readFile、read、writeFile、write都是将整个文件放入内存而再操作,而则是文件一部分数据一部分数据操作;

 *

 * -----------------------流读取-------------------------------------

 * 读取数据对象:

 * fs.ReadStream 读取文件

 * http.IncomingMessage 客户端请求或服务器端响应

 * net.Socket    Socket端口对象

 * child.stdout  子进程标准输出

 * child.stdin   子进程标准入

 * process.stdin 用于创建进程标准输入流

 * Gzip、Deflate、DeflateRaw   数据压缩

 *

 * 触发事件:

 * readable  数据可读时

 * data      数据读取后

 * end       数据读取完成时

 * error     数据读取错误时

 * close     关闭流对象时

 *

 * 读取数据的对象操作方法:

 * read      读取数据方法

 * setEncoding   设置读取数据的编码

 * pause     通知对象众目停止触发data事件

 * resume    通知对象恢复触发data事件

 * pipe      设置数据通道,将读入流数据接入写入流;

 * unpipe    取消通道

 * unshift   当流数据绑定一个解析器时,此方法取消解析器

 *

 * ------------------------流写入-------------------------------------

 * 写数据对象:

 * fs.WriteStream           写入文件对象

 * http.clientRequest       写入HTTP客户端请求数据

 * http.ServerResponse      写入HTTP服务器端响应数据

 * net.Socket               读写TCP流或UNIX流,需要connection事件传递给用户

 * child.stdout             子进程标准输出

 * child.stdin              子进程标准入

 * Gzip、Deflate、DeflateRaw  数据压缩

 *

 * 写入数据触发事件:

 * drain            当write方法返回false时,表示缓存区中已经输出到目标对象中,可以继续写入数据到缓存区

 * finish           当end方法调用,全部数据写入完成

 * pipe             当用于读取数据的对象的pipe方法被调用时

 * unpipe           当unpipe方法被调用

 * error            当发生错误

 *

 * 写入数据方法:

 * write            用于写入数据

 * end              结束写入,之后再写入会报错;

 */

 

获取文件信息

fs.open的第一个参数是文件路径,第二个参数是一些用来指示以什么模式打开文件的标记,这些标记可以是r,r+,w,w+,a或者a+。下面是这些标记的说明(来自UNIX文档的fopen页)

28、path.extname(path)

获取路径中的扩展名,如果没有'.',则返回空

 

语法

以下为在异步模式下打开文件的语法格式:

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

                   path.extname('/a/b/index.html');

13、修改文件或目录的操作权限

//fs.utimes(path, mode, callback);

/**

 * path, 要查看目录/文件的完整路径及名;

 * mode, 指定权限,如:0666 8进制,权限:所有用户可读、写,

 * [callback(err)], 操作完成回调函数;err操作失败对象

 */

 

1.        fs.chmod(__dirname + '/fsDir', 0666, function (err) {

2.            if(err) {

3.                console.error(err);

4.                return;

5.            }

6.            console.log('修改权限成功')

7.        });

 

实例

接下来我们创建 file.js 文件,代码如下所示:

var fs = require("fs");
// 执行前创建一个空的 /tmp/test 目录
console.log("准备删除目录 /tmp/test");
fs.rmdir("/tmp/test",function(err){
   if (err) {
       return console.error(err);
   }
   console.log("读取 /tmp 目录");
   fs.readdir("/tmp/",function(err, files){
      if (err) {
          return console.error(err);
      }
      files.forEach( function (file){
          console.log( file );
      });
   });
});

以上代码执行结果如下:

$ node file.js 
准备删除目录 /tmp/test
读取 /tmp 目录
……

 

                   path.exists('/does_not_exist', function(exists) {

15、删除空目录

//fs.rmdir(path, callback);

/**

 * path, 目录的完整路径及目录名;

 * [callback(err)], 操作完成回调函数;err操作失败对象

 */

1.        fs.rmdir(__dirname + '/test', function (err) {

2.            fs.mkdir(__dirname + '/test', 0666, function (err) {

3.                console.log('创建test目录');

4.            });

5.         

6.            if(err) {

7.                console.log('删除空目录失败,可能原因:1、目录不存在,2、目录不为空')

8.                console.error(err);

9.                return;

10.         }

11.      

12.         console.log('删除空目录成功!');

13.     });

 

 

// => '/foo/bar/baz/asdf'

27、path.basename(path, [ext]). 21

创建目录

                   var path = require('path');

14、移动/重命名文件或目录... 10

语法

以下为异步模式下写入文件的语法格式:

fs.writeFile(file, data[, options], callback)

如果文件存在,该方法写入的内容会覆盖旧的文件内容。

小结

5、读文件,读取打开的文件内容到缓冲区中;

// fs.read(fd, buffer, offset, length, position, callback);

/**

 * fd, 使用fs.open打开成功后返回的文件描述符

 * buffer, 一个Buffer对象,v8引擎分配的一段内存

 * offset, 整数,向缓存区中写入时的初始位置,以字节为单位

 * length, 整数,读取文件的长度

 * position, 整数,读取文件初始位置;文件大小以字节为单位

 * callback(err, bytesRead, buffer), 读取执行完成后回调函数,bytesRead实际读取字节数,被读取的缓存区对象

 */

 

1.        fs.open(__dirname + '/test.txt', 'r', function (err, fd) {

2.            if(err) {

3.                console.error(err);

4.                return;

5.            } else {

6.                var buffer = new Buffer(255);

7.                console.log(buffer.length);

8.                //每一个汉字utf8编码是3个字节,英文是1个字节

9.                fs.read(fd, buffer, 0, 9, 3, function (err, bytesRead, buffer) {

10.                 if(err) {

11.                     throw err;

12.                 } else {

13.                     console.log(bytesRead);

14.                     console.log(buffer.slice(0, bytesRead).toString());

15.                     //读取完后,再使用fd读取时,基点是基于上次读取位置计算;

16.                     fs.read(fd, buffer, 0, 9, null, function (err, bytesRead, buffer) {

17.                         console.log(bytesRead);

18.                         console.log(buffer.slice(0, bytesRead).toString());

19.                     });

20.                 }

21.             });

22.         }

23.     });

 

读取目录

幸运的是,Node有个叫path的模块,可以帮你标准化,连接,解析路径,从绝对路径转换到相对路径,从路径中提取各部分信息,检测文件是否存在。总的来说,path模块其实只是些字符串处理,而且也不会到文件系统去做验证(path.exists函数例外)。

29、path.sep属性

返回操作系统中文件分隔符; window是'\', Unix是'/'

 

语法

以下为异步模式下截取文件的语法格式:

fs.ftruncate(fd, len, callback)

该方法使用了文件描述符来读取文件。

                   var fs = require('fs');

9、读取目录;

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

//fs.readdir(path, callback);

/**

 * path, 要读取目录的完整路径及目录名;

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

 */

1.        fs.readdir(__dirname + '/fsDir/', function (err, files) {

2.            if(err) {

3.                console.error(err);

4.                return;

5.            } else {

6.                files.forEach(function (file) {

7.                    var filePath = path.normalize(__dirname + '/fsDir/' + file);

8.                    fs.stat(filePath, function (err, stat) {

9.                        if(stat.isFile()) {

10.                         console.log(filePath + ' is: ' + 'file');

11.                     }

12.                     if(stat.isDirectory()) {

13.                         console.log(filePath + ' is: ' + 'dir');

14.                     }

15.                 });

16.             });

17.             for (var i = 0; i < files.length; i++) {

18.                 //使用闭包无法保证读取文件的顺序与数组中保存的致

19.                 (function () {

20.                     var filePath = path.normalize(__dirname + '/fsDir/' + files[i]);

21.                     fs.stat(filePath, function (err, stat) {

22.                         if(stat.isFile()) {

23.                             console.log(filePath + ' is: ' + 'file');

24.                         }

25.                         if(stat.isDirectory()) {

26.                             console.log(filePath + ' is: ' + 'dir');

27.                         }

28.                     });

29.                 })();

30.             }

31.         }

32.     });

 

 

2.stats.isFile() —— 如果是个标准文件,而不是目录,socket,符号链接或者设备,则返回true,否则false
3.stats.isDiretory() —— 如果是目录则返回tue,否则false
4.stats.isBlockDevice() —— 如果是块设备则返回true,在大多数UNIX系统中块设备通常都在/dev目录下
5.stats.isChracterDevice() —— 如果是字符设备返回true
6.stats.isSymbolickLink() —— 如果是文件链接返回true
7.stats.isFifo() —— 如果是个FIFO(UNIX命名管道的一个特殊类型)返回true
8.stats.isSocket() —— 如果是个UNIX socket(TODO:googe it)

4、打开文件... 3

 

                   if (readBytes > 0) {

 

语法

以下为异步模式下关闭文件的语法格式:

fs.close(fd, callback)

该方法使用了文件描述符来读取文件。

注意:从Node0.8版本开始,exists从path模块移到了fs模块,变成了fs.exists,除了命名空间不同,其它都没变:

19、创建读取流

//fs.createReadStream(path, [options])

/**

 * path 文件路径

 * [options] flags:指定文件操作,默认'r',读操作;encoding,指定读取流编码;autoClose, 是否读取完成后自动关闭,默认true;start指定文件开始读取位置;end指定文件开始读结束位置

 */

1.        var rs = fs.createReadStream(__dirname + '/test.txt', {start: 0, end: 2});

2.         

3.        //open是ReadStream对象中表示文件打开时事件,

4.        rs.on('open', function (fd) {

5.            console.log('开始读取文件');

6.        });

7.         

8.        rs.on('data', function (data) {

9.            console.log(data.toString());

10.     });

11.      

12.     rs.on('end', function () {

13.         console.log('读取文件结束')

14.     });

15.      

16.     rs.on('close', function () {

17.         console.log('文件关闭');

18.     });

19.      

20.     rs.on('error', function (err) {

21.         console.error(err);

22.     });

23.      

24.     //暂停和回复文件读取;

25.      

26.     rs.on('open', function () {

27.         console.log('开始读取文件');

28.     });

29.      

30.     rs.pause();

31.      

32.     rs.on('data', function (data) {

33.         console.log(data.toString());

34.     });

35.      

36.     setTimeout(function () {

37.         rs.resume();

38.     }, 2000);

写入文件

                            console.log(readBuffer.slice(0, readBytes));

1、读取文件readFile函数

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

/**

 * filename, 必选参数,文件名

 * [options],可选参数,可指定flag(文件操作选项,如r+ 读写;w+ 读写,文件不存在则创建)及encoding属性

 * callback 读取文件后的回调函数,参数默认第一个err,第二个data 数据

 */

1.        fs.readFile(__dirname + '/test.txt', {flag: 'r+', encoding: 'utf8'}, function (err, data) {

2.            if(err) {

3.                console.error(err);

4.                return;

5.            }

6.            console.log(data);

7.        });

实例

接下来我们创建 file.js 文件,代码如下所示:

var fs = require("fs");
var buf = new Buffer(1024);

console.log("准备打开文件!");
fs.open('input.txt', 'r+', function(err, fd) {
   if (err) {
       return console.error(err);
   }
   console.log("文件打开成功!");
   console.log("准备读取文件!");
   fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
      if (err){
         console.log(err);
      }

      // 仅输出读取的字节
      if(bytes > 0){
         console.log(buf.slice(0, bytes).toString());
      }

      // 关闭文件
      fs.close(fd, function(err){
         if (err){
            console.log(err);
         } 
         console.log("文件关闭成功");
      });
   });
});

以上代码执行结果如下:

$ node file.js 
准备打开文件!
文件打开成功!
准备读取文件!
菜鸟教程官网地址:www.runoob.com
文件关闭成功

                   path.extname('/a/b.c/d.');

23、路径结合、合并,路径最后不会带目录分隔符

//path.join([path1],[path2]..[pathn]);

/**

 * [path1] 路径或表示目录的字符,

 */

 

1.        var path1 = 'path1',

2.            path2 = 'path2//pp\',

3.            path3 = '../path3'

4.         

5.        var myPath = path.join(path1, path2, path3);

6.        console.log(myPath); //path1path2path3

实例

input.txt 文件内容为:

菜鸟教程官网地址:www.runoob.com

接下来我们创建 file.js 文件,代码如下所示:

var fs = require("fs");
var buf = new Buffer(1024);

console.log("准备打开已存在的文件!");
fs.open('input.txt', 'r+', function(err, fd) {
   if (err) {
       return console.error(err);
   }
   console.log("文件打开成功!");
   console.log("准备读取文件:");
   fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
      if (err){
         console.log(err);
      }
      console.log(bytes + "  字节被读取");

      // 仅输出读取的字节
      if(bytes > 0){
         console.log(buf.slice(0, bytes).toString());
      }
   });
});

以上代码执行结果如下:

$ node file.js 
准备打开已存在的文件!
文件打开成功!
准备读取文件:
42  字节被读取
菜鸟教程官网地址:www.runoob.com

 

复制代码 代码如下:

1.        var fs = require('fs'),

 

path.basename还可以接受一个扩展名字符串作为第二个参数,这样返回的文件名就会自动去掉扩展名,仅仅返回文件的名称部分:

16、监视文件

//对文件进行监视,并且在监视到文件被修改时执行处理

//fs.watchFile(filename, [options], listener);

/**

 * filename, 完整路径及文件名;

 * [options], persistent true表示持续监视,不退出程序;interval 单位毫秒,表示每隔多少毫秒监视一次文件

 * listener, 文件发生变化时回调,有两个参数:curr为一个fs.Stat对象,被修改后文件,prev,一个fs.Stat对象,表示修改前对象

 */

1.        fs.watchFile(__dirname + '/test.txt', {interval: 20}, function (curr, prev) {

2.            if(Date.parse(prev.ctime) == 0) {

3.                console.log('文件被创建!');

4.            } else if(Date.parse(curr.ctime) == 0) {

5.                console.log('文件被删除!')

6.            } else if(Date.parse(curr.mtime) != Date.parse(prev.mtime)) {

7.                console.log('文件有修改');

8.            }

9.        });

10.      

11.     fs.watchFile(__dirname + '/test.txt', function (curr, prev) {

12.         console.log('这是第二个watch,监视到文件有修改');

13.     });

 

 

var readBuffer = new Buffer(1024),

8、创建目录;7

var fs = require("fs")

                   fs.exists('/does_not_exist', function(exists) {

17、取消监视文件... 12

实例

接下来我们创建 file.js 文件,并打开 input.txt 文件进行读写,代码如下所示:

var fs = require("fs");

// 异步打开文件
console.log("准备打开文件!");
fs.open('input.txt', 'r+', function(err, fd) {
   if (err) {
       return console.error(err);
   }
  console.log("文件打开成功!");     
});

以上代码执行结果如下:

node file.js 
准备打开文件!
文件打开成功!

    var writeBuffer = new Buffer('writing this string'),

目录

参数

参数使用说明如下:

  • path - 文件路径。

  • callback - 回调函数,没有参数。

                  fs.stat('/etc/passwd', function(err, stats) {

24、获取绝对路径... 20

参数

参数使用说明如下:

  • fd - 通过 fs.open() 方法返回的文件描述符。

  • buffer - 数据写入的缓冲区。

  • offset - 缓冲区写入的写入偏移量。

  • length - 要从文件中读取的字节数。

  • position - 文件读取的起始位置,如果 position 的值为 null,则会从当前文件指针的位置读取。

  • callback - 回调函数,有三个参数err, bytesRead, buffer,err 为错误信息, bytesRead 表示读取的字节数,buffer 为缓冲区对象。

                   }

7、刷新缓存区;

// 使用fs.write写入文件时,操作系统是将数据读到内存,再把数据写入到文件中,当数据读完时并不代表数据已经写完,因为有一部分还可能在内在缓冲区内。

// 因此可以使用fs.fsync方法将内存中数据写入文件;--刷新内存缓冲区;

//fs.fsync(fd, [callback])

/**

 * fd, 使用fs.open打开成功后返回的文件描述符

 * [callback(err, written, buffer)], 写入操作执行完成后回调函数,written实际写入字节数,buffer被读取的缓存区对象

 */

1.        fs.open(__dirname + '/test.txt', 'a', function (err, fd) {

2.            if(err)

3.                throw err;

4.            var buffer = new Buffer('我爱nodejs编程');

5.         

6.            fs.write(fd, buffer, 0, 9, 0, function (err, written, buffer) {

7.                console.log(written.toString());

8.                fs.write(fd, buffer, 9, buffer.length - 9, null, function (err, written) {

9.                    console.log(written.toString());

10.                 fs.fsync(fd);

11.                 fs.close(fd);

12.             })

13.         });

14.     });

 

关闭文件

                   });

11、查看文件与目录的是否存在... 9

参数

参数使用说明如下:

  • path - 文件路径。

  • mode - 设置目录权限,默认为 0777。

  • callback - 回调函数,没有参数。

连接路径

30、path.delimiter属性... 21

读取文件

复制代码 代码如下:

将Node.js的文件系统、文件流及路径操作API详细的学习了一下,代码都是测试过的,也许很简单,但为了打好基础,还是要有点一丝不苟的精神,从中我也更深入理解异步回调事件机制,希望对你有用……

 

你可能注意到了,到目前为止,本章的所有例子都没有关闭文件的代码。因为它们只是些仅使用一次而且又小又简单的例子,当Node进程结束时,操作系统会确保关闭所有文件。

2、写文件

// fs.writeFile(filename,data,[options],callback);

var w_data = '这是一段通过fs.writeFile函数写入的内容;rn';

var w_data = new Buffer(w_data);

 

/**

 * filename, 必选参数,文件名

 * data, 写入的数据,可以字符或一个Buffer对象

 * [options],flag,mode(权限),encoding

 * callback 读取文件后的回调函数,参数默认第一个err,第二个data 数据

 */

1.        fs.writeFile(__dirname + '/test.txt', w_data, {flag: 'a'}, function (err) {

2.            if(err) {

3.                console.error(err);

4.            } else {

5.                console.log('写入成功');

6.            }

7.        });

 

打开文件

但是,在实际的应用程序中,一旦打开一个文件你要确保最终关闭它。要做到这一点,你需要追踪所有那些已打开的文件描述符,然后在不再使用它们的时候调用fs.close(fd[,callback])来最终关闭它们。如果你不仔细的话,很容易就会遗漏某个文件描述符。下面的例子提供了一个叫openAndWriteToSystemLog的函数,展示了如何小心的关闭文件:

15、删除空目录... 11

参数

参数使用说明如下:

  • fd - 通过 fs.open() 方法返回的文件描述符。

  • callback - 回调函数,没有参数。

                  });

3、以追加方式写文件... 3

 

在存储或使用路径之前将它们标准化通常是个好主意。比如,由用户输入或者配置文件获得的文件路径,或者由两个或多个路径连接起来的路径,一般都应该被标准化。可以用path模块的normalize函数来标准化一个路径,而且它还能处理“..”,“.”“//”。比如:

16、监视文件... 11

删除目录

        function wrote(err, written) {

26、path.dirname(p)

// 获取路径中目录名

1.        var myPath = path.dirname(__dirname + '/test/util you.mp3');

2.        console.log(myPath);

 

实例

接下来我们创建 file.js 文件,代码如下所示:

var fs = require("fs");

console.log("创建目录 /tmp/test/");
fs.mkdir("/tmp/test/",function(err){
   if (err) {
       return console.error(err);
   }
   console.log("目录创建成功。");
});

以上代码执行结果如下:

$ node file.js 
创建目录 /tmp/test/
目录创建成功。

         filePosition,

22、路径解析,得到规范化的路径格式... 19

 

fs.read(fd,

 

 

复制代码 代码如下:

20、创建写入流

//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],  写入后回调

 */

 

1.        var ws = fs.createWriteStream(__dirname + '/test.txt', {start: 0});

2.         

3.        var buffer = new Buffer('我也喜欢你');

4.         

5.         

6.        ws.write(buffer, 'utf8', function (err, buffer) {

7.            console.log(arguments);

8.            console.log('写入完成,回调函数没有参数')

9.        });

10.      

11.     //最后再写入的内容

12.     ws.end('再见');

13.      

14.     //使用流完成复制文件操作

15.     var rs = fs.createReadStream(__dirname + '/test.txt')

16.     var ws = fs.createWriteStream(__dirname + '/test/test.txt');

17.     rs.on('data', function (data) {

18.         ws.write(data)

19.     });

20.      

21.     ws.on('open', function (fd) {

22.         console.log('要写入的数据文件已经打开,文件描述符是: ' + fd);

23.     });

24.      

25.     rs.on('end', function () {

26.         console.log('文件读取完成');

27.      

28.         ws.end('完成', function () {

29.             console.log('文件全部写入完成')

30.         });

31.     });

 

//关于WriteStream对象的write方法返回一个布尔类型,当缓存区中数据全部写满时,返回false;

//表示缓存区写满,并将立即输出到目标对象中

 

//第一个例子

1.        var ws = fs.createWriteStream(__dirname + '/test/test.txt');

2.        for (var i = 0; i < 10000; i++) {

3.            var w_flag = ws.write(i.toString());

4.            //当缓存区写满时,输出false

5.            console.log(w_flag);

6.        }

 

//第二个例子

1.        var ws = fs.createWriteStream(__dirname + '/test/untiyou.mp3');

2.        var rs = fs.createReadStream(__dirname + '/test/Until You.mp3');

3.        rs.on('data', function (data) {

4.            var flag = ws.write(data);

5.            console.log(flag);

6.        });

7.         

8.        //系统缓存区数据已经全部输出触发drain事件

9.        ws.on('drain', function () {

10.         console.log('系统缓存区数据已经全部输出。')

11.     });

 

 

});

9、读取目录;7

 

 

                   fs.open('/path/to/file', 'r', function(err, fd) {

11、查看文件与目录的是否存在

//fs.exists(path, callback);

/**

 * path, 要查看目录/文件的完整路径及名;

 * [callback(exists)], 操作完成回调函数;exists true存在,false表示不存在

 */

1.        fs.exists(__dirname + '/te', function (exists) {

2.            var retTxt = exists ? retTxt = '文件存在' : '文件不存在';

3.            console.log(retTxt);

4.        });

 

参数

参数使用说明如下:

  • path - 文件的路径。

  • flags - 文件打开的行为。具体值详见下文。

  • mode - 设置文件模式(权限),文件创建默认权限为 0666(可读,可写)。

  • callback - 回调函数,带有两个参数如:callback(err, fd)。

flags 参数可以是以下值:

flag 描述
r 以读取模式打开文件。如果文件不存在抛出异常。
r+ 以读写模式打开文件。如果文件不存在抛出异常。
rs 以同步的方式读取文件。
rs+ 以同步的方式读取和写入文件。
w 以写入模式打开文件,如果文件不存在则创建。
wx 类似 'w',但是如果文件路径存在,则文件写入失败。
w+ 以读写模式打开文件,如果文件不存在则创建。
wx+ 类似 'w+', 但是如果文件路径存在,则文件读写失败。
a 以追加模式打开文件,如果文件不存在则创建。
ax 类似 'a', 但是如果文件路径存在,则文件追加失败。
a+ 以读取追加模式打开文件,如果文件不存在则创建。
ax+ 类似 'a+', 但是如果文件路径存在,则文件读取追加失败。

mode: 33188,

19、创建读取流... 15

异步和同步

Node.js 文件系统(fs 模块)模块中的方法均有异步和同步版本,例如读取文件内容的函数有异步的 fs.readFile() 和同步的 fs.readFileSync()。

异步的方法函数最后一个参数为回调函数,回调函数的第一个参数包含了错误信息(error)。

建议大家是用异步方法,比起同步,异步方法性能更高,速度更快,而且没有阻塞。

通过传递给fs.write()传递一个包含数据的缓冲对象,来往一个已打开的文件里写数据:

10、查看文件与目录的信息;

//fs.stat(path, callback);

//fs.lstat(path, callback); //查看符号链接文件

/**

 * path, 要查看目录/文件的完整路径及名;

 * [callback(err, stats)], 操作完成回调函数;err错误对象,stat fs.Stat一个对象实例,提供如:isFile, isDirectory,isBlockDevice等方法及size,ctime,mtime等属性

 */

//实例,查看fs.readdir

 

语法

以下为删除文件的语法格式:

fs.unlink(path, callback)

路径的标准化

25、获取相对路径

//path.relative(from, to);

//获取两路径之间的相对关系

/**

 * from 当前路径,并且方法返回值是基于from指定到to的相对路径

 * to   到哪路径,

 */

1.        var from = 'c:\from\a\',

2.            to = 'c:/test/b';

3.        var _path = path.relative(from, to);

4.        console.log(_path); //....testb; 表示从from到to的相对路径

 

截取文件

                   path.dirname('/foo/bar/baz/asdf/quux.txt');

10、查看文件与目录的信息;8

 

目前为止,前面涉及到的路径处理操作都跟底层文件系统无关,只是一些字符串操作。然而,有些时候你需要判断一个文件路径是否存在,比如,你有时候需要判断文件或目录是否存在,如果不存在的话才创建它,可以用path.exsits():

26、path.dirname(p). 20

1.缓冲区的数据
2.待写数据从缓冲区的什么位置开始
3.待写数据的长度
4.数据写到文件的哪个位置
5.当操作结束后被调用的回调函数wrote

2.            path = require('path');

1.r —— 以只读方式打开文件,数据流的初始位置在文件开始
2.r+ —— 以可读写方式打开文件,数据流的初始位置在文件开始
3.w ——如果文件存在,则将文件长度清0,即该文件内容会丢失。如果不存在,则尝试创建它。数据流的初始位置在文件开始
4.w+ —— 以可读写方式打开文件,如果文件不存在,则尝试创建它,如果文件存在,则将文件长度清0,即该文件内容会丢失。数据流的初始位置在文件开始
5.a —— 以只写方式打开文件,如果文件不存在,则尝试创建它,数据流的初始位置在文件末尾,随后的每次写操作都会将数据追加到文件后面。
6.a+ ——以可读写方式打开文件,如果文件不存在,则尝试创建它,数据流的初始位置在文件末尾,随后的每次写操作都会将数据追加到文件后面。

17、取消监视文件

//取消对文件进行监视

//fs.unwatchFile(filename, [listener]);

/**

 * filename, 完整路径及文件名;

 * [listener], 要取消的监听器事件,如果不指定,则取消所有监听处理事件

 */

1.        var listener = function (curr, prev) {

2.            console.log('我是监视函数')

3.        }

4.        fs.unwatchFile(__dirname + '/test.txt', listener);

 

16、监视文件或目录

// 对文件或目录进行监视,并且在监视到修改时执行处理;

// fs.watch返回一个fs.FSWatcher对象,拥有一个close方法,用于停止watch操作;

// 当fs.watch有文件变化时,会触发fs.FSWatcher对象的change(err, filename)事件,err错误对象,filename发生变化的文件名

// fs.watch(filename, [options], [listener]);

/**

 * filename, 完整路径及文件名或目录名;

 * [listener(event, filename], 监听器事件,有两个参数:event 为rename表示指定的文件或目录中有重命名、删除或移动操作或change表示有修改,filename表示发生变化的文件路径

 */

 

1.        var fsWatcher = fs.watch(__dirname + '/test', function (event, filename) {

2.            //console.log(event)

3.        });

4.         

5.        //console.log(fsWatcher instanceof FSWatcher);

6.         

7.        fsWatcher.on('change', function (event, filename) {

8.            console.log(filename + ' 发生变化')

9.        });

10.      

11.     //30秒后关闭监视

12.     setTimeout(function () {

13.         console.log('关闭')

14.         fsWatcher.close(function (err) {

15.             if(err) {

16.                 console.error(err)

17.             }

18.             console.log('关闭watch')

19.         });

20.     }, 30000);

 

计算两个绝对路径的相对路径

18、文件流... 13

                   path.join('/foo', 'bar', 'baz/asdf', 'quux', '..');

12、修改文件访问时间与修改时间... 9

blksize: 4096,

5、读文件,读取打开的文件内容到缓冲区中;... 4

                 path.existsSync('/etc/passwd');

2、写文件... 1

                   });

 

var fs = require('fs');
function openAndWriteToSystemLog(writeBuffer, callback){
    fs.open('./my_file', 'a', function opened(err, fd) {
        if (err) { return callback(err); }
        function notifyError(err) {
            fs.close(fd, function() {
                callback(err);
            });
        }
        var bufferOffset = 0,
        bufferLength = writeBuffer.length,
        filePosition = null;
        fs.write( fd, writeBuffer, bufferOffset, bufferLength, filePosition,
            function wrote(err, written) {
                if (err) { return notifyError(err); }
                fs.close(fd, function() {
                    callback(err);
                });
            }
        );
    });
}
openAndWriteToSystemLog(
    new Buffer('writing this string'),
    function done(err) {
        if (err) {
            console.log("error while opening and writing:", err.message);
            return;
        }
        console.log('All done with no errors');
    }
);

6、写文件,将缓冲区内数据写入使用fs.open打开的文件... 5

复制代码 代码如下:

20、创建写入流... 16

                                    if (err) { throw err;}

27、path.basename(path, [ext])

// 获取路径中文件名,后缀是可选的,如果加,请使用'.ext'方式来匹配,则返回值中不包括后缀名;

1.        var myPath = path.basename(__dirname + '/test/util you.mp3', '.mp3');

2.        console.log(myPath);

 

 { dev: 234881026,

4、打开文件

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

/**

 * filename, 必选参数,文件名

 * flags, 操作标识,如"r",读方式打开

 * [mode],权限,如777,表示任何用户读写可执行

 * callback 打开文件后回调函数,参数默认第一个err,第二个fd为一个整数,表示打开文件返回的文件描述符,window中又称文件句柄

 */

1.        fs.open(__dirname + '/test.txt', 'r', '0666', function (err, fd) {

2.            console.log(fd);

3.        });

 

复制代码 代码如下:

 

         bufferOffset,

29、path.sep 属性... 21

1.有错误发生
2.成功读取了数据
3.没有数据可读

如果有错误发生,第一个参数(err)会为回调函数提供一个包含错误信息的对象,否则这个参数为null。如果成功读取了数据,第二个参数(readBytes)会指明被读到缓冲区里数据的大小,如果值是0,则表示到达了文件末尾。

path.exists()是个I/O操作,因为它是异步的,因此需要一个回调函数,当I/O操作返回后调用这个回调函数,并把结果传递给它。你还可以使用它的同步版本path.existsSync(),功能完全一样,只是它不会调用回调函数,而是直接返回结果:

本章覆盖了文件处理的基础知识,包括如何打开文件,读取文件某一部分,写数据,以及关闭文件。

                            console.log('exists:', exists);

fs模块包含所有文件查询和处理的相关函数,用这些函数,可以查询文件信息,读写和关闭文件。这样导入fs模块:

         function read(err, readBytes) {

                        // got fd file descriptor

var path = require('path');

这块代码片断会有类似下面的输出

文件路径里可能还包含文件扩展名,通常是文件名中最后一个“.”字符之后的那部分字符串。

                   // => '.'

           console.log('wrote ' + written + ' bytes');

nlink: 1,

                   path.basename('/foo/bar/baz/asdf/quux.html', '.html');

                path.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb');

用path.resolve()可以把多个路径解析为一个绝对路径。它的功能就像对这些路径挨个不断进行“cd”操作,和cd命令的参数不同,这些路径可以是文件,并且它们不必真实存在——path.resolve()方法不会去访问底层文件系统来确定路径是否存在,它只是一些字符串操作。

复制代码 代码如下:

                   // => ''

复制代码 代码如下:

注意那个内部函数notifyError,它会关闭文件,并报告发生的错误。

                   // => '/foo/bar/baz/asdf'

gid: 0,

rdev: 0,

 或者,你想从文件路径里得到文件名,也就是文件路径的最后那一部分,可以使用path.basename函数:  

打开文件

跟read操作一样,千万不要在fs.write执行过程中使用哪个传入的缓冲区对象,一旦fs.write开始执行它就获得了那个缓冲区对象的控制权。你只能等到回调函数被调用后才能再重新使用它。

复制代码 代码如下:

有时你可能需要知道文件的大小,创建日期或者权限等文件信息,可以使用fs.stath函数来查询文件或目录的元信息:

});

ino: 95028917,

                   // => quux.html  

上面代码尝试打开一个文件,当成功打开后(调用opened函数),开始请求从文件流第100个字节开始读取随后1024个字节的数据(第11行)。

ctime: Thu, 08 Sep 2011 23:50:04 GMT }

});

                   // => '.html'

                   path.exists('/etc/passwd', function(exists) {

Node有一组数据流API,可以像处理网络流那样处理文件,用起来很方便,但是它只允许顺序处理文件,不能随机读写文件。因此,需要使用一些更底层的文件系统操作。

当有错误发生时,你应该总是使用正确的错误处理逻辑来关闭文件——以确保在调用返回前关闭那些已打开的文件描述符。

处理文件路径

1.fs.stat()调用会将一个stats类的实例作为参数传递给它的回调函数,可以像下面这样使用stats实例:

uid: 0,

                            // => false

复制代码 代码如下:

atime: Fri, 18 Nov 2011 22:44:47 GMT,

                            console.log('exists:', exists);

mtime: Thu, 08 Sep 2011 23:50:04 GMT,

                    var path = require('path');

复制代码 代码如下:

注意:一旦把缓冲区对象传递给fs.open(),缓冲对象的控制权就转移给给了read命令,只有当回调函数被调用,缓冲区对象的控制权才会回到你手里。因此在这之前,不要读写或者让其它函数调用使用这个缓冲区对象;否则,你可能会读到不完整的数据,更糟的情况是,你可能会并发地往这个缓冲区对象里写数据。

         readBuffer,

                   path.extname('/a/b.c/index');

有3个特殊的文件描述符——1,2和3。他们分别代表标准输入,标准输出和标准错误文件描述符。标准输入,顾名思义,是个只读流,进程用它来从控制台或者进程通道读取数据。标准输出和标准错误是仅用来输出数据的文件描述符,他们经常被用来向控制台,其它进程或文件输出数据。标准错误负责错误信息输出,而标准输出负责普通的进程输出。

Node的很多文件API几乎是UNIX(POSIX)中对应文件API 的翻版,比如使用文件描述符的方式,就像UNIX里一样,文件描述符在Node里也是一个整型数字,代表一个实体在进程文件描述符表里的索引。

                   path.resolve('/foo/bar', './baz');

path.relative()可以告诉你如果从一个绝对地址跳转到另外一个绝对地址,比如:

                   // => quux

                   // => /foo/bar/baz/asdf

                 // => true

           if (err) { throw err; }

当你使用文件时,多数情况下都需要处理和提取文件路径信息,通过使用path模块你可以连接路径,标准化路径,计算路径的差别,以及将相对路径转化成绝对路径。你可以提取指定文件路径的扩展名,文件名,目录等路径组件。

以路径“/foo/bar/myfile.txt”为例,如果你想获取父目录(/foo/bar)的所有内容,或者读取同级目录的其它文件,为此,你必须用path.dirname(filePath)获得文件路径的目录部分,比如:

    fs.write( fd,

    if (err) { throw err; }

注意:到此为止,你知道了如何使用底层的原子操作来打开,读,写和关闭文件。然而,Node还有一组更高级的构造函数,允许你用更简单的方式来处理文件。

         bufferLength,

比如:

                  var path = require('path');

    bufferLength = writeBuffer.length, filePosition = null;

var fs = require('fs');

复制代码 代码如下:

blocks: 0,

                   });

fs.open('./my_file.txt', 'a', function opened(err, fd) {

                   var fs = require('fs');

这个例子里,filePostion参数为null,也就是说write函数将会把数据写到文件指针当前所在的位置,因为是以追加模式打开的文件,因此文件指针在文件末尾。

                            // => false

size: 5086,

         var fs = require(‘fs')

                var path = require('path');

还有,如果你想读取一个文件的某个区域,可以考虑使用ReadStream。这两种用例会在第九章“数据的读,写流”里介绍。

        filePosition,

        bufferPosition,

                   var path = require('path');

几乎所有跟文件相关的操作都会涉及到处理文件路径,本章先会将介绍这些工具函数,然后再深入讲解文件读写和数据操作

    bufferPosition = 0,

                   path.extname('/a/b.c/.');

fs.read()的最后一个参数是个回调函数(第16行),当下面三种情况发生时,它会被调用:

                   var path = require('path');

                   // => /tmp/file

关闭文件

        writeBuffer,

普通文件不受这种限制,比如Node里,你即可以创建只能向尾部追加数据的文件,还可以创建读写随机位置的文件。

fs模块介绍

检查路径是否存在

复制代码 代码如下:

                            // => true

                   if (err) { throw err; }

复制代码 代码如下:

复制代码 代码如下:

复制代码 代码如下:

        });

fs.open('./my_file.txt', 'r', function opened(err, fd) {

                                    console.log(stats);

filePosition = 100;

如果解析结果不是绝对路径,path.resolve()会把当前工作目录作为路径附加到解析结果前面,比如:

path.normalize('/foo/bar//baz/asdf/quux/..');

                   path.basename('/foo/bar/baz/asdf/quux.html')

                   });

bufferLength = readBuffer.length,

复制代码 代码如下:

  在这儿,提供了一个叫openAndWriteToSystemLog的函数,它接受一个包含待写数据的缓冲区对象,以及一个操作完成或者出错后被调用的回调函数,如果有错误发生,回调函数的第一个参数会包含这个错误对象。

                   var path = require('path');

复制代码 代码如下:

查询文件信息

                            console.log('exists:', exists);

        path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif');
        // 如果当前工作目录是/home/myself/node, 将返回
        // => /home/myself/node/wwwroot/static_files/gif/image.gif'

解析路径

                   path.resolve('/foo/bar', '/tmp/file/');

这个例子里,第2(译者注:原文为3)行代码尝试用追加模式(a)打开一个文件,然后第7行代码(译者注:原文为9)向文件写入数据。缓冲区对象需要附带几个信息一起做为参数:

复制代码 代码如下:

复制代码 代码如下:

在读取或处理文件之前,必须先使用fs.open函数打开文件,然后你提供的回调函数会被调用,并得到这个文件的描述符,稍后你可以用这个文件描述符来读写这个已经打开的文件:

                   // => ''

if (err) { throw err }

本文由美高梅网址发布于新闻中心,转载请注明出处:js文件操作详解,js操作详解

上一篇:没有了 下一篇:没有了
猜你喜欢
热门排行
精彩图文