当前位置:嗨网首页>书籍在线阅读

09-文件流

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

6.3.5 文件流

我们已经了解了可读流和可写流,不过我想多花点时间对它们进行更深入的介绍。

你可以通过 fs.createReadStream() 创建一个可写流、传入一个路径和一个 options 对象,或者在 options 中指定文件描述,这样路径就可以为空。这种方式同样适用于用 fs.createWriteStream() 创建的可写流。它们都支持 options 对象。默认情况下,可以用下面的方式创建一个可写流:

{ flags: 'r',
  encoding: null,
  fd: null,
  mode: 0o666,
  autoClose: true
}

如果想用文件描述符,可以在 options 中设置它。 autoClose 参数会在读取文件后自动关闭文件。如果只想读取文件的一部分内容,可以用 startend 设置起始位置和终止位置(以字节为单位)。你可以声明编码方式为UTF-8或其他,也可以在后面用 setEncoding() 来设置。

**关于流的文档很分散** 可以在用 `fs.createReadStream()` 创建的可读流中调用 `set-Encoding()` 这个功能,实际上是在Node文档的流部分提到的。如果你正在使用Node流,要注意的是相关的文档很分散,需要仔细查找。

稍后我会提供一个文件系统可读流的例子,不过先让我们看看如何用 fs.create- WriteStream() 创建可写流需要的参数。下面是默认参数:

{ flags: 'w',
  defaultEncoding: 'utf8',
  fd: null,
  mode: 0o666 }

同样,你可以不用路径而改用文件描述符。在可写流中使用 defaultEncoding 设置编码,而非 encoding 。如果想从文件的某个特定位置开始写入,可以通过 start 参数来设置。这里不指定 end 参数是因为写入内容结束后的位置就是结束的位置。

现在我们来整体看看上面讲到的内容。在例6-2中,我打开了一个文件,并使用可写流进行修改。修改的过程是在文件指定位置插入一个字符串。在本例中我用了文件描述符,这意味着程序在调用 fs.createWriteStream() 时,它不会在创建可写流的同时打开文件。

例6-2 通过插入字符串修改已有文件

var fs = require('fs');
fs.open('./working.txt', 'r+',function (err, fd) {
   if (err) return console.error(err);
   var writable = fs.createWriteStream(null,{fd: fd, start: 10,
                                        defaultEncoding: 'utf8'});
   writable.write(' inserting this text ');
});

注意在打开文件时用了 r+ 的标识,这让程序既能读文件也能修改文件。

在例6-3中,我会打开同一个文件,只不过这次需要读取文件内容。由于只需要读取,所以用了默认的 r 标识。然后我读取了所有内容。

不过,我用 setEncoding() 把编码格式改成了 utf8 。在例6-2中,我通过 default- Encoding 参数在写入文件时把格式调成了 utf8

例6-3 用流读取文件内容

var fs = require('fs');
var readable =
  fs.createReadStream('./working.txt').setEncoding('utf8');
var data = '';
readable.on('data', function(chunk) {
   data += chunk;
});
readable.on('end', function() {
   console.log(data);
});

在修改文件前后分别调用读文件程序,就能看到修改的内容。第一次运行读文件程序会返回working.txt的内容:

Now let's pull this all together, and read and write with a stream.

修改后再次运行则会返回:

Now let's  inserting this text  and read and write with a stream.

如果我们打开文件之后,将读取出来的内容传入可写流中,这将节省我们很多时间。我们可以简单地使用可读流上的 pipe() 函数。但是,我们不能中途修改结果,因为可写流只提供写入功能,它不是双工流。换句话说,它不是能修改内容的转换流。不过你可以把内容从一个文件复制到另一个文件。

var fs = require('fs');
var readable =
  fs.createReadStream('./working.txt');
var writable = fs.createWriteStream('./working2.txt');
readable.pipe(writable);

稍后在6.6节中我们会看到真正的转换流。