可写流的使用
可写流的创建
Node.js 中的可写流使用 stream
模块中的 Writable
类表示,使用该类时,需要重写其中的 write()
方法,因此要使用 stream
模块中的 Writable
类创建可写流,需要使用的代码类似下面代码:
const stream = require('stream');
const writable = new stream.Writable({
write: function (chunk, encoding, next) {
console.log(chunk.toString());
next();
}
});
另外,还可以使用 fs
模块的 createWriteStream()
方法创建可写流,语法格式如下:
fs.createWriteStream(path[, options])
-
path
:写入文件的文件路径。 -
options
:写入文件时的可选参数,可选值如下。-
flags
:指定文件系统的权限,默认为w
,如果要修改文件内容,而不是替换,需要将该值设置为a
。 -
encoding
:编码方式,默认为null
。 -
fd
:文件描述符,默认为null
。 -
mode
:设置文件模式,默认为0o666
。 -
autoClose
:文件出错或者结束时,是否自动关闭文件,默认为true
。 -
emitClose
:流销毁时,是否发送close
事件,默认为true
。 -
start
:指定开始写入的位置。 -
highWaterMark
:可写入的阈值,一般设置在 16~100KB 范围内。
-
例如,下面代码创建一个可写流:
var fs = require("fs");
var write = fs.createWriteStream('demo.txt'); //创建可写流
可写流的属性方法及事件
可写流提供了很多属性、方法和事件,用来获取可写流信息、对可写流进行操作,以及监听可写流的相应操作,它们的说明分别如表10.4、表10.5和表10.6所示。



可写流的常见操作
写入数据
使用 write()
方法可以向流中写入数据,其语法格式如下:
对象名.write( chunk[, encoding, callback])
-
chunk
:要写入的数据,其值可以是字符串、缓冲区或数组等。 -
encoding
:可选参数,表示写入数据时的编码方式。 -
callback
:可选参数,是一个回调函数,写入数据完成后执行。
【例10.3】使用可写流为文件追加内容。(实例位置:资源包\源码\10\03)
使用 fs
模块的 createWriteStream
方法创建一个可写流对象,然后使用其 write
方法为古诗《凉州词》追加诗词赏析内容。代码如下:
const fs = require("fs")
var txt = "这首诗抓住了边塞风光景物的一些特点,借其严寒春迟及胡笳声声来写战士们的心理活动,反映了边关将士的生活状
况。诗风苍凉悲壮,但并不低沉,以侠骨柔情为壮士之声,这仍然是盛唐气象的回响。"
//在文件原有内容后面追加内容,所以定义文件权限为“a”
var decr = fs.createWriteStream("凉州词.txt", {flags: "a"})
decr.write("\n鉴赏:\n" + txt, "utf8") //写入内容
本实例的运行效果可参考图10.3和图10.4。
设置编码方式
使用 setDefaultEncoding()
方法可以设置可写流的默认编码方式,其语法格式如下:
对象名.setDefaultEncoding(encoding)
参数 encoding
表示要设置的编码方式。
例如,创建可写流,并将写入数据的编码方式设置为 utf8
,代码如下:
const fs = require("fs")
var writeSteam = fs.createWriteStream("demo.txt")
writeSteam.setDefaultEncoding("utf8") //设置编码方式
writeSteam.write("测试数据") //写入内容
关闭流
写入流的 end()
方法用来标识已经没有需要写入流中的数据了,因此通常用来关闭流,其语法格式如下:
对象名.end([chunk[, encoding]][, callback])
-
chunk
:可选参数,表示关闭流之前要写入的数据。 -
encoding
:如果chunk
为字符串,那么encoding
为编码方式。 -
callback
:流结束或者报错时的回调函数。
例如,下面代码中在关闭流之前写入一段数据:
const fs = require("fs")
var writeSteam = fs.createWriteStream("demo.txt")
writeSteam.setDefaultEncoding("utf8") //设置编码方式
writeSteam.write("测试数据") //写入内容
writeSteam.end("写入完成") //关闭流
//writeSteam.write('继续写入');
运行程序,demo.txt
文件中内容如下:
测试数据
写入完成
使用 ![]() Figure 4. 图10.5 关闭流后继续写入数据时的错误提示
|
销毁流
使用 destroy()
方法可以销毁所创建的写入流,并且流被销毁后,无法再向流写入数据。其语法格式如下:
对象名.destroy([error])
参数 error
为可选参数,表示使用 error
事件触发的错误。
例如,下面代码使用写入流向一个文件中写入了一个字符串,使用 destroy()
方法销毁创建的写入流,代码如下:
const fs = require("fs")
var writeSteam = fs.createWriteStream("demo.txt")
writeSteam.setDefaultEncoding("utf8") //设置编码方式
writeSteam.write("测试数据") //写入内容
writeSteam.destroy() //销毁流
上面代码运行后,将会导致 demo.txt
文件中没有任何数据,因为虽然第 4 行代码中使用 write()
方法写入了数据,但由于紧接着销毁了写入流,这将导致使用该流执行的任何操作都会失效。因此,在使用写入流销毁操作时,通常在异常处理中使用该操作。
一旦流被销毁,就无法对其进行任何操作,并且销毁流时,使用 |
将数据缓冲到内存
使用写入流的 cork()
方法可以强制把所有写入的数据都缓冲到内存中,它的主要目的是为了适应将几个数据快速连续地写入流的情况。cork()
方法不会立即将它们转发到底层目标处,而是缓冲所有数据块,直到调用 uncork()
方法。cork()
方法的语法格式如下:
对象名.cork()
当使用 |
例如,下面代码创建一个写入流,并在控制台中输出一句话,然后调用 cork()
方法后,在控制台中输出另外一句话,代码如下:
const stream = require('stream');
const writable = new stream.Writable({
write: function (chunk, encoding, next) {
console.log(chunk.toString());
next();
}
});
writable.write('天气晴朗');
writable.cork();
writable.write('阳光明媚');
运行结果如下:
天气晴朗
通过观察上面结果,发现调用 cork()
方法后,接下来要输出的内容并没有显示。
输出缓冲后的数据
前面介绍了 cork()
方法,用以强制把所有写入的数据都缓冲到内存中,而使用 uncork()
方法可以将调用 cork()
方法后缓冲的所有数据输出到目标处。uncork()
方法的语法格式如下:
对象名.uncork()
例如,修改上面的示例,在其最后代码下方添加一行代码,调用写入流的 uncork()
方法,即代码修改如下:
const stream = require('stream');
const writable = new stream.Writable({
write: function (chunk, encoding, next) {
console.log(chunk.toString());
next();
}
});
writable.write('天气晴朗');
writable.cork();
writable.write('阳光明媚');
writable.uncork();
运行上面代码,效果如下:
天气晴朗
阳光明媚