因为Node.js是运行在服务区端的JavaScript环境,服务器程序和浏览器程序相比,最大的特点是没有浏览器的安全限制了,而且,服务器程序必须能接收网络请求,读写文件,处理二进制内容,所以,Node.js内置的常用模块就是为了实现基本的服务器功能。这些模块在浏览器环境中是无法被执行的,因为它们的底层代码是用C/C++在Node.js运行环境中实现的。
fs模块
Node.js内置的fs模块就是文件系统模块,负责读写文件。和所有其它JavaScript模块不同的是,fs模块同时提供了异步1和同步的方法。
异步方法的最后一个参数都是一个回调函数。 传给回调函数的参数取决于具体方法,但回调函数的第一个参数都会保留给异常。 如果操作成功完成,则第一个参数会是 null 或 undefined。
当使用同步方法时,任何异常都会被立即抛出。 可以使用 try/catch 来处理异常,或让异常向上冒泡。
异步方法的例子:
const fs = require('fs');
fs.unlink('/tmp/hello', (err) => {
if (err) throw err;
console.log('成功删除 /tmp/hello');
});
同步方法的例子:
const fs = require('fs');
fs.unlinkSync('/tmp/hello');
console.log('成功删除 /tmp/hello');
异步的方法不能保证执行顺序。 所以下面的例子可能会出错:
fs.rename('/tmp/hello', '/tmp/world', (err) => {
if (err) throw err;
console.log('重命名完成');
});
fs.stat('/tmp/world', (err, stats) => {
if (err) throw err;
console.log(`文件属性: ${JSON.stringify(stats)}`);
});
fs.stat 可能在 fs.rename 之前执行。 正确的方法是把回调链起来。
fs.rename('/tmp/hello', '/tmp/world', (err) => {
if (err) throw err;
fs.stat('/tmp/world', (err, stats) => {
if (err) throw err;
console.log(`文件属性: ${JSON.stringify(stats)}`);
});
});
在繁忙的进程中,建议使用异步的方法。 同步的方法会阻塞整个进程,直到完成(停止所有连接)。
可以使用文件名的相对路径。 路径是相对 process.cwd() 的。
公共引用
const fs = require('fs');
模块方法
fs.readFile(path, options, callback)
path <string> | <Buffer> | <URL> | <integer>
:文件名或文件描述符。options <Object> | <string>(可省)
:
encoding <string> | <null>
:默认为 null。flag <string>
:默认为 ‘r’。
callback <Function>
:
err <Error>
data <string> | <Buffer>
异步地读取一个文件的全部内容。
示例:
fs.readFile('/etc/passwd', (err, data) => {
if (err) throw err;
console.log(data);
});
回调有两个参数 (err, data),其中 data 是文件的内容。
如果未指定字符编码,则返回原始的 buffer。
如果 options 是一个字符串,则它指定了字符编码。
fs.readFile('/etc/passwd', 'utf8', callback);
fs.writeFile(file, data, [options], callback)
file <string> | <Buffer> | <integer>
:文件名或文件描述符data <string> | <Buffer> | <Uint8Array>
options <Object> | <string>
:
bencoding <string> | <null>
默认 = ‘utf8’mode <integer>
:默认 = 0o666flag <string>
:默认 = ‘w’
callback <Function>
:
err <Error>
异步地写入数据到文件,如果文件已经存在,则替代文件。 data 可以是一个字符串或一个 buffer。
如果 data 是一个 buffer,则忽略 encoding 选项。它默认为 ‘utf8’。
示例:
fs.writeFile('message.txt', 'Hello Node.js', (err) => {
if (err) throw err;
console.log('The file has been saved!');
});
如果 options 是一个字符串,则它指定了字符编码。
fs.writeFile('message.txt', 'Hello Node.js', 'utf8', callback);
fs.appendFile(file, data, [options], callback)
file <string> | <Buffer> | <number>
:文件名或文件描述符data <string> | <Buffer>
options <Object> | <string>
:
encoding <string> | <null>
:默认为 ‘utf8’mode <integer>
:默认为 0o666flag <string>
:默认为 ‘a’
callback <Function>
:
err <Error>
异步地追加数据到一个文件,如果文件不存在则创建文件。 data 可以是一个字符串或 buffer。
示例:
fs.appendFile('message.txt', 'data to append', (err) => {
if (err) throw err;
console.log('The "data to append" was appended to file!');
});
如果 options 是一个字符串,则它指定了字符编码。
fs.appendFile('message.txt', 'data to append', 'utf8', callback);
任何指定的文件描述符必须为了追加而被打开。
注意:如果文件描述符被指定为 file,则不会被自动关闭。
stream模块
http模板
url模板
path模板
querystring模板
公共引用:
const querystring = require("querystring")
模块方法:
querystring.parse(str, sep, eq, options)
str <string>
:要解析的 URL 查询字符串。sep <string>(可省)
:用于界定查询字符串中的键值对的子字符串。默认为 ‘&’。eq <string>(可省)
:用于界定查询字符串中的键与值的子字符串。默认为 ‘=’。options <Object>(可省)
:
decodeURIComponent <Function>
解码查询字符串的字符时使用的函数。默认为 querystring.unescape()。maxKeys <number>
指定要解析的键的最大数量。默认为 1000。指定为 0 则不限制。
该方法会把一个 URL 查询字符串 str 解析成一个键值对的集合,也就是将一个字符串反序列化为一个对象
示例:
querystring.parse("name=whitemu&sex=man&sex=women");
/*
return:
{ name: 'whitemu', sex: [ 'man', 'women' ] }
*/
querystring.parse("name=whitemu#sex=man#sex=women","#",null,{maxKeys:2});
/*
return:
{ name: 'whitemu', sex: 'man' }
*/
querystring.stringify(obj,separator,eq,options)
obj <Object>
: 要序列化成 URL 查询字符串的对象。sep <string>(可省)
:用于界定查询字符串中的键值对的子字符串。默认为 ‘&’。eq <string>(可省)
:用于界定查询字符串中的键与值的子字符串。默认为 ‘=’。options(可省)
encodeURIComponent <Function>
:把对象中的字符转换成查询字符串时使用的函数。默认为 querystring.escape()。
该方法通过遍历给定的 obj 对象的自身属性,生成 URL 查询字符串,即是将一个对象序列化成一个字符串,与querystring.parse相对
如果 obj 对象中的属性的类型为<string> | <number> | <boolean> | <string[]> | <number[]> | <boolean[]>
,则属性的值会被序列化。 其他类型的属性的值会被强制转换为空字符串。
示例:
querystring.stringify({name: 'whitemu', sex: [ 'man', 'women' ] });
/*
return:
'name=whitemu&sex=man&sex=women'
*/
querystring.stringify({name: 'whitemu', sex: [ 'man', 'women' ] },"*","$");
/*
return:
'name$whitemu*sex$man*sex$women'
*/
querystring.escape(str)
str <string>
对给定的 str 进行 URL 编码。该方法是提供给 querystring.stringify() 使用的,通常不直接使用。 它之所以对外开放,是为了在需要时可以通过给 querystring.escape 赋值一个函数来重写编码的实现。
示例:
querystring.escape("name=慕白");
/*
return:
'name%3D%E6%85%95%E7%99%BD'
*/
querystring.unescape(str)
str <string>
对给定的 str 进行解码。该方法是提供给 querystring.parse() 使用的,通常不直接使用。 它之所以对外开放,是为了在需要时可以通过给 querystring.unescape 赋值一个函数来重写解码的实现。
默认使用 JavaScript 内置的 decodeURIComponent() 方法来解码。
示例:
querystring.unescape('name%3D%E6%85%95%E7%99%BD');
/*
return:
'name=慕白'
*/
参考资料:
1. 基本模块
2. Node.js v8.9.0 文档
3. nodejs之querystring模块
4. nodejs之fs模块
- 因为JavaScript的单线程模型,执行IO操作时,JavaScript代码无需等待,而是传入回调函数后,继续执行后续JavaScript代码 ↩