Node.js Manual & Documentation
Table Of Contents
- Synopsis 概要
- Global Objects 全局对象
- global
- process
- require()
- require.resolve()
- require.paths
- __filename
- __dirname
- module
- Timers 定时器
- setTimeout(callback, delay, [arg], [...])
- clearTimeout(timeoutId)
- setInterval(callback, delay, [arg], [...])
- clearInterval(intervalId)
- Modules 模块
- Core Modules 核心模块
- File Modules 文件模块
- Loading from `node_modules` Folders 从 `node_modules` 目录中加载
- Optimizations to the `node_modules` Lookup Process 优化 `node_modules` 的查找过程
- Folders as Modules 目录作为模块
- Caching 缓存
- All Together... 总结一下...
- Loading from the `require.paths` Folders 从`require.paths`目录中加载
- Note:** Please Avoid Modifying `require.paths` **注意:** 请不要修改`requires.paths`
- Setting `require.paths` to some other value does nothing. 将`require.paths`设为其他值不会产生任何作用
- Putting relative paths in `require.paths` is... weird. 不建议在`require.paths`中发入相对路径
- Zero Isolation 零隔离
- Note:** Please Avoid Modifying `require.paths` **注意:** 请不要修改`requires.paths`
- Addenda: Package Manager Tips 附录:包管理技巧
- Addons 扩展插件
- process 进程
- Event: 'exit' 事件:'exit'
- Event: 'uncaughtException' 事件:'uncaughtException'
- Signal Events 信号事件
- process.stdout
- process.stderr
- process.stdin
- process.argv
- process.execPath
- process.chdir(directory)
- process.cwd()
- process.env
- process.exit(code=0)
- process.getgid()
- process.setgid(id)
- process.getuid()
- process.setuid(id)
- process.version
- process.installPrefix
- process.kill(pid, signal='SIGTERM')
- process.pid
- process.title
- process.platform
- process.memoryUsage()
- process.nextTick(callback)
- process.umask([mask])
- util 工具模块
- util.debug(string)
- util.log(string)
- util.inspect(object, showHidden=false, depth=2)
- util.pump(readableStream, writableStream, [callback])
- util.inherits(constructor, superConstructor)
- Events 事件模块
- events.EventEmitter
- emitter.addListener(event, listener)
- emitter.on(event, listener)
- emitter.once(event, listener)
- emitter.removeListener(event, listener)
- emitter.removeAllListeners(event)
- emitter.setMaxListeners(n)
- emitter.listeners(event)
- emitter.emit(event, [arg1], [arg2], [...])
- Event: 'newListener' 事件:'newListener'
- events.EventEmitter
- Buffers 缓冲器
- new Buffer(size)
- new Buffer(array)
- new Buffer(str, encoding='utf8')
- buffer.write(string, offset=0, encoding='utf8')
- buffer.toString(encoding, start=0, end=buffer.length)
- buffer[index]
- Buffer.isBuffer(obj)
- Buffer.byteLength(string, encoding='utf8')
- buffer.length
- buffer.copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
- buffer.slice(start, end=buffer.length)
- Streams 流
- Readable Stream 可读流
- Event: 'data' 事件:'data'
- Event: 'end' 事件:'end'
- Event: 'error' 事件:'error'
- Event: 'close' 事件:'close'
- Event: 'fd' 事件:'fd'
- stream.readable
- stream.setEncoding(encoding)
- stream.pause()
- stream.resume()
- stream.destroy()
- stream.destroySoon()
- stream.pipe(destination, [options])
- Writable Stream 可写流
- Event: 'drain' 事件:'drain'
- Event: 'error' 事件:'error'
- Event: 'close' 事件:'close'
- Event: 'pipe' 事件:'pipe'
- stream.writable
- stream.write(string, encoding='utf8', [fd])
- stream.write(buffer)
- stream.end()
- stream.end(string, encoding)
- stream.end(buffer)
- stream.destroy()
- Crypto 加密模块
- crypto.createCredentials(details)
- crypto.createHash(algorithm)
- hash.update(data)
- hash.digest(encoding='binary')
- crypto.createHmac(algorithm, key)
- hmac.update(data)
- hmac.digest(encoding='binary')
- crypto.createCipher(algorithm, key)
- cipher.update(data, input_encoding='binary', output_encoding='binary')
- cipher.final(output_encoding='binary')
- crypto.createDecipher(algorithm, key)
- decipher.update(data, input_encoding='binary', output_encoding='binary')
- decipher.final(output_encoding='binary')
- crypto.createSign(algorithm)
- signer.update(data)
- signer.sign(private_key, output_format='binary')
- crypto.createVerify(algorithm)
- verifier.update(data)
- verifier.verify(cert, signature, signature_format='binary')
- TLS (SSL) TLS (SSL)模块
- s = tls.connect(port, [host], [options], callback)
- tls.Server
- tls.createServer(options, secureConnectionListener)
- Event: 'secureConnection' 事件:'secureConnection'
- server.listen(port, [host], [callback])
- server.close()
- server.maxConnections
- server.connections
- File System 文件系统模块
- fs.rename(path1, path2, [callback])
- fs.renameSync(path1, path2)
- fs.truncate(fd, len, [callback])
- fs.truncateSync(fd, len)
- fs.chmod(path, mode, [callback])
- fs.chmodSync(path, mode)
- fs.stat(path, [callback])
- fs.lstat(path, [callback])
- fs.fstat(fd, [callback])
- fs.statSync(path)
- fs.lstatSync(path)
- fs.fstatSync(fd)
- fs.link(srcpath, dstpath, [callback])
- fs.linkSync(srcpath, dstpath)
- fs.symlink(linkdata, path, [callback])
- fs.symlinkSync(linkdata, path)
- fs.readlink(path, [callback])
- fs.readlinkSync(path)
- fs.realpath(path, [callback])
- fs.realpathSync(path)
- fs.unlink(path, [callback])
- fs.unlinkSync(path)
- fs.rmdir(path, [callback])
- fs.rmdirSync(path)
- fs.mkdir(path, mode, [callback])
- fs.mkdirSync(path, mode)
- fs.readdir(path, [callback])
- fs.readdirSync(path)
- fs.close(fd, [callback])
- fs.closeSync(fd)
- fs.open(path, flags, mode=0666, [callback])
- fs.openSync(path, flags, mode=0666)
- fs.utimes(path, atime, mtime, callback)
- fs.utimesSync(path, atime, mtime)
- fs.futimes(path, atime, mtime, callback)
- fs.futimesSync(path, atime, mtime)
- fs.write(fd, buffer, offset, length, position, [callback])
- fs.writeSync(fd, buffer, offset, length, position)
- fs.writeSync(fd, str, position, encoding='utf8')
- fs.read(fd, buffer, offset, length, position, [callback])
- fs.readSync(fd, buffer, offset, length, position)
- fs.readSync(fd, length, position, encoding)
- fs.readFile(filename, [encoding], [callback])
- fs.readFileSync(filename, [encoding])
- fs.writeFile(filename, data, encoding='utf8', [callback])
- fs.writeFileSync(filename, data, encoding='utf8')
- fs.watchFile(filename, [options], listener)
- fs.unwatchFile(filename)
- fs.Stats
- fs.ReadStream
- fs.createReadStream(path, [options])
- fs.WriteStream
- Event: 'open' 事件:'open'
- fs.createWriteStream(path, [options])
- Path 路径模块
- path.normalize(p)
- path.join([path1], [path2], [...])
- path.resolve([from ...], to)
- path.dirname(p)
- path.basename(p, [ext])
- path.extname(p)
- path.exists(p, [callback])
- path.existsSync(p)
- net 网络模块
- net.createServer([options], [connectionListener])
- net.createConnection(arguments...)
- net.Server
- server.listen(port, [host], [callback])
- server.listen(path, [callback])
- server.listenFD(fd)
- server.close()
- server.address()
- server.maxConnections
- server.connections
- Event: 'connection' 事件:'connection'
- Event: 'close'
- net.Socket
- new net.Socket([options])
- socket.connect(port, [host], [callback])
- socket.connect(path, [callback])
- socket.bufferSize
- socket.setEncoding(encoding=null)
- socket.setSecure()
- socket.write(data, [encoding], [callback])
- socket.write(data, [encoding], [fileDescriptor], [callback])
- socket.end([data], [encoding])
- socket.destroy()
- socket.pause()
- socket.resume()
- socket.setTimeout(timeout, [callback])
- socket.setNoDelay(noDelay=true)
- socket.setKeepAlive(enable=false, [initialDelay])
- socket.remoteAddress
- Event: 'connect' 事件:'connect'
- Event: 'data' 事件:'data'
- Event: 'end' 事件:'end'
- Event: 'timeout' 事件:'timeout'
- Event: 'drain' 事件:'drain'
- Event: 'error' 事件:'error'
- Event: 'close' 事件:'close'
- net.isIP
- net.isIP(input)
- net.isIPv4(input)
- net.isIPv6(input)
- DNS DNS模块
- dns.lookup(domain, family=null, callback)
- dns.resolve(domain, rrtype='A', callback)
- dns.resolve4(domain, callback)
- dns.resolve6(domain, callback)
- dns.resolveMx(domain, callback)
- dns.resolveTxt(domain, callback)
- dns.resolveSrv(domain, callback)
- dns.reverse(ip, callback)
- UDP / Datagram Sockets 数据报套接字模块
- Event: 'message' 事件:'message'
- Event: 'listening' 事件:'listening'
- Event: 'close' 事件:'close'
- dgram.createSocket(type, [callback])
- dgram.send(buf, offset, length, path, [callback])
- dgram.send(buf, offset, length, port, address, [callback])
- dgram.bind(path)
- dgram.bind(port, [address])
- dgram.close()
- dgram.address()
- dgram.setBroadcast(flag)
- dgram.setTTL(ttl)
- dgram.setMulticastTTL(ttl)
- dgram.setMulticastLoopback(flag)
- dgram.addMembership(multicastAddress, [multicastInterface])
- dgram.dropMembership(multicastAddress, [multicastInterface])
- HTTP HTTP模块
- http.Server
- Event: 'request' 事件:'request'
- Event: 'connection' 事件:'connection'
- Event: 'close' 事件:'close'
- Event: 'request' 事件:'request'
- Event: 'checkContinue' 事件:'checkContinue'
- Event: 'upgrade' 事件:'upgrade'
- Event: 'clientError' 事件:'clientError'
- http.createServer(requestListener)
- server.listen(port, [hostname], [callback])
- server.listen(path, [callback])
- server.close()
- http.ServerRequest
- Event: 'data' 事件:'data'
- Event: 'end' 事件:'end'
- request.method
- request.url
- request.headers
- request.trailers
- request.httpVersion
- request.setEncoding(encoding=null)
- request.pause()
- request.resume()
- request.connection
- http.ServerResponse
- response.writeContinue()
- response.writeHead(statusCode, [reasonPhrase], [headers])
- response.statusCode
- response.setHeader(name, value)
- response.getHeader(name)
- response.removeHeader(name)
- response.write(chunk, encoding='utf8')
- response.addTrailers(headers)
- response.end([data], [encoding])
- http.request(options, callback)
- http.get(options, callback)
- http.Agent
- http.getAgent(host, port)
- Event: 'upgrade' 事件:'upgrade'
- Event: 'continue' 事件:'continue'
- agent.maxSockets
- agent.sockets
- agent.queue
- http.ClientRequest
- Event 'response' 事件:'response'
- request.write(chunk, encoding='utf8')
- request.end([data], [encoding])
- request.abort()
- http.ClientResponse
- Event: 'data' 事件:'data'
- Event: 'end' 事件:'end'
- response.statusCode
- response.httpVersion
- response.headers
- response.trailers
- response.setEncoding(encoding=null)
- response.pause()
- response.resume()
- https.Server
- https.createServer
- https.request(options, callback)
- https.get(options, callback)
- URL URL模块
- url.parse(urlStr, parseQueryString=false)
- url.format(urlObj)
- url.resolve(from, to)
- Query String 查询字符串模块
- querystring.stringify(obj, sep='&', eq='=')
- querystring.parse(str, sep='&', eq='=')
- querystring.escape
- querystring.unescape
- REPL 交互式解释器
- repl.start(prompt='> ', stream=process.stdin)
- REPL Features REPL特性
- Child Processes 子进程
- Event: 'exit' 事件:'exit'
- child.stdin
- child.stdout
- child.stderr
- child.pid
- child_process.spawn(command, args=[], [options])
- child_process.exec(command, [options], callback)
- child.kill(signal='SIGTERM')
- Assert 断言模块
- assert.fail(actual, expected, message, operator)
- assert.ok(value, [message])
- assert.equal(actual, expected, [message])
- assert.notEqual(actual, expected, [message])
- assert.deepEqual(actual, expected, [message])
- assert.notDeepEqual(actual, expected, [message])
- assert.strictEqual(actual, expected, [message])
- assert.notStrictEqual(actual, expected, [message])
- assert.throws(block, [error], [message])
- assert.doesNotThrow(block, [error], [message])
- assert.ifError(value)
- TTY 终端模块
- tty.open(path, args=[])
- tty.isatty(fd)
- tty.setRawMode(mode)
- tty.setWindowSize(fd, row, col)
- tty.getWindowSize(fd)
- os Module 操作系统模块
- os.hostname()
- os.type()
- os.release()
- os.uptime()
- os.loadavg()
- os.totalmem()
- os.freemem()
- os.cpus()
- Debugger 调试器
- Advanced Usage 高级用法
- Appendixes 附录
- Appendix 1 - Third Party Modules 附录 1 - 第三方模块
Synopsis 概要
An example of a web server written with Node which responds with 'HelloWorld':
下边是一个用Node编写的对所有请求简单返回'Hello World‘的web服务器例子:
var http = require('http');
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World\n');
}).listen(8124);
console.log('Server running at http://127.0.0.1:8124/');
To run the server, put the code into a file called example.js
and executeit with the node program
要运行这个服务器程序,只要将上述代码保存为文件example.js
并用node程序执行此文件:
> node example.js
Server running at http://127.0.0.1:8124/
All of the examples in the documentation can be run similarly.
此文档中所有例子均可用同样的方法运行。## Global Objects 全局对象
These object are available in the global scope and can be accessed from anywhere.
这些对象在全局范围内均可用,你可以在任何位置访问这些对象。
global
The global namespace object.
全局命名空间对象
In browsers, the top-level scope is the global scope. That means that inbrowsers if you're in the global scopevar something
will define a globalvariable. In Node this is different. The top-level scope is not the globalscope;var something
inside a Node module will be local to that module.
在浏览器中,顶级作用域为全局作用域,在全局作用域下通过var something
即定义了一个全局变量。但是在Node中并不如此,顶级作用域并非是全局作用域,在Node模块中通过var something
定义的变量仅作用于该模块。
process
The process object. See the 'process object' section.
进程对象,参见'process object'章节。
require()
To require modules. See the 'Modules' section.
加载模块,参见'Modules'章节。
require.resolve()
Use the internal require()
machinery to look up the location of a module,but rather than loading the module, just return the resolved filename.
使用内部函数require()
的机制查找一个模块的位置,而不用加载模块,只是返回解析后的文件名。
require.paths
An array of search paths for require()
. This array can be modified to addcustom paths.
require()
的搜索路径数组,你可以修改该数组添加自定义的搜索路径。
Example: add a new path to the beginning of the search list
例如:将一个新的搜索路径插入到搜索列表的头部。
require.paths.unshift('/usr/local/node');
__filename
The filename of the script being executed. This is the absolute path, and not necessarilythe same filename passed in as a command line argument.
当前正在执行的脚本的文件名。这是一个绝对路径,可能会和命令行参数中传入的文件名不同。
Example: running node example.js
from /Users/mjr
例如:在目录/Users/mjr
下运行node example.js
console.log(__filename);
// /Users/mjr/example.js
__dirname
The dirname of the script being executed.
当前正在执行脚本所在的目录名。
Example: running node example.js
from /Users/mjr
例如:在目录/Users/mjr
下运行node example.js
console.log(__dirname);
// /Users/mjr
module
A reference to the current module. In particularmodule.exports
is the same as theexports
object. See src/node.js
for more information.
指向当前模块的引用。特别的,当你通过module.exports
和exports
两种方式访问的将是同一个对象,参见src/node.js
。
Timers 定时器
setTimeout(callback, delay, [arg], [...])
To schedule execution of callback
after delay
milliseconds. Returns atimeoutId
for possible use withclearTimeout()
. Optionally, you canalso pass arguments to the callback.
设定一个delay
毫秒后执行callback
回调函数的计划。返回值timeoutId
可被用于clearTimeout()
。可以设定要传递给回调函数的参数。
clearTimeout(timeoutId)
Prevents a timeout from triggering.
清除定时器,阻止指定的timeout(超时)定时器被触发。
setInterval(callback, delay, [arg], [...])
To schedule the repeated execution of callback
every delay
milliseconds.Returns aintervalId
for possible use with clearInterval()
. Optionally,you can also pass arguments to the callback.
设定一个每delay
毫秒重复执行callback
回调函数的计划。返回值intervalId
可被用于clearInterval()
。可以设定要传递给回调函数的参数。
clearInterval(intervalId)
Stops a interval from triggering.
清除定时器,阻止指定的interval(间隔)定时器被触发。## Modules 模块
Node uses the CommonJS module system.Node has a simple module loading system. In Node, files and modules are inone-to-one correspondence. As an example,foo.js
loads the modulecircle.js
in the same directory.
Node使用CommonJS模块系统。Node有一个简单的模块装载系统,在Node中,文件和模块是一一对应的。下面的例子展示了foo.js
文件如何在相同的目录中加载circle.js
模块。
The contents of foo.js
:
foo.js
的内容为:
var circle = require('./circle.js');
console.log( 'The area of a circle of radius 4 is '
+ circle.area(4));
The contents of circle.js
:
circle.js
的内容为:
var PI = Math.PI;
exports.area = function (r) {
return PI * r * r;
};
exports.circumference = function (r) {
return 2 * PI * r;
};
The module circle.js
has exported the functions area()
andcircumference()
. To export an object, add to the specialexports
object.
circle.js
模块输出了area()
和circumference()
两个函数,为了以对象的形式输出,需将要输出的函数加入到一个特殊的exports
对像中。
Variableslocal to the module will be private. In this example the variable PI
isprivate to circle.js
.
模块的本地变量是私有的。在上面的例子中,变量PI
就是circle.js
私有的。
Core Modules 核心模块
Node has several modules compiled into the binary. These modules aredescribed in greater detail elsewhere in this documentation.
Node有一些编译成二进制的模块。这些模块在这篇文档的其他地方有详细描述。
The core modules are defined in node's source in the lib/
folder.
核心模块在node源代码中的lib文件夹下。
Core modules are always preferentially loaded if their identifier ispassed to require()
. For instance, require('http')
will alwaysreturn the built in HTTP module, even if there is a file by that name.
核心模块总是被优先加载,如果它们的标识符被require()
调用。例如,require('http')
将总是返回内建的HTTP模块,即便又一个同名文件存在。
File Modules 文件模块
If the exact filename is not found, then node will attempt to load therequired filename with the added extension of.js
, and then .node
..js
files are interpreted as JavaScript text files, and.node
filesare interpreted as compiled addon modules loaded with dlopen
.
如果没有找到确切的文件名,node将尝试以追加扩展名.js
后的文件名读取文件,如果还是没有找到则尝试追加扩展名.node
。.js
文件被解释为JavaScript格式的纯文本文件,.node
文件被解释为编译后的addon(插件)模块,并使用dlopen
来加载。
A module prefixed with '/'
is an absolute path to the file. Forexample,require('/home/marco/foo.js')
will load the file at/home/marco/foo.js
.
以'/'
为前缀的模块是一个指向文件的绝对路径,例如require('/home/marco/foo.js')
将加载文件/home/marco/foo.js
。
A module prefixed with './'
is relative to the file calling require()
.That is, circle.js
must be in the same directory asfoo.js
forrequire('./circle')
to find it.
以'./'
为前缀的模块是指向文件的相对路径,相对于调用require()
的文件。也就是说为了使require('./circle')
能找到正确的文件,circle.js
必须位于与foo.js
相同的路径之下。
Without a leading '/' or './' to indicate a file, the module is either a"core module" or is loaded from anode_modules
folder.
如果标明一个文件时没有 '/' 或 './'前缀,该模块或是"核心模块",或者位于 node_modules
目录中。
Loading from `node_modules` Folders 从 `node_modules` 目录中加载
If the module identifier passed to require()
is not a native module,and does not begin with'/'
, '../'
, or './'
, then node starts at theparent directory of the current module, and adds/node_modules
, andattempts to load the module from that location.
如果传递到 require()
的模块标识符不是一个核心模块,并且不是以'/'
,'../'
或'./'
开头,node将从当前模块的父目录开始,在其/node_modules
子目录中加载该模块。
If it is not found there, then it moves to the parent directory, and soon, until either the module is found, or the root of the tree isreached.
如果在那里没有找到,就转移到上一级目录,依此类推,直到找到该模块或到达目录树的根结点。
For example, if the file at '/home/ry/projects/foo.js'
calledrequire('bar.js')
, then node would look in the following locations, inthis order:
例如,如果在文件 '/home/ry/projects/foo.js'
中调用 `require('bar.js'),node将会依次查找以下位置:
/home/ry/projects/node_modules/bar.js
/home/ry/node_modules/bar.js
/home/node_modules/bar.js
/node_modules/bar.js
This allows programs to localize their dependencies, so that they do notclash.
这允许程序本地化他们的依赖关系,避免发生冲突。
Optimizations to the `node_modules` Lookup Process 优化 `node_modules` 的查找过程
When there are many levels of nested dependencies, it is possible forthese file trees to get fairly long. The following optimizations are thusmade to the process.
如果有很多级的嵌套信赖,文件树会变得相当的长,下面是对这一过程的一些优化。
First, /node_modules
is never appended to a folder already ending in/node_modules
.
首先, /node_modules
不要添加到以 /node_modules
结尾的目录上。
Second, if the file calling require()
is already inside a node_modules
hierarchy, then the top-mostnode_modules
folder is treated as theroot of the search tree.
其次,如果调用require()
的文件已经位于一个node_modules
层次中,最上级的node_modules
目录将被作为搜索的根。
For example, if the file at'/home/ry/projects/foo/node_modules/bar/node_modules/baz/quux.js'
calledrequire('asdf.js')
, then node would search the followinglocations:
例如,如果文件'/home/ry/projects/foo/node_modules/bar/node_modules/baz/quux.js'
调用require('asdf.js')
,node会在下面的位置进行搜索:
/home/ry/projects/foo/node_modules/bar/node_modules/baz/node_modules/asdf.js
/home/ry/projects/foo/node_modules/bar/node_modules/asdf.js
/home/ry/projects/foo/node_modules/asdf.js
Folders as Modules 目录作为模块
It is convenient to organize programs and libraries into self-containeddirectories, and then provide a single entry point to that library.There are three ways in which a folder may be passed torequire()
asan argument.
很方便将程序或库组织成自包含的目录,并提供一个单独的入口指向那个库。有三种方式可以将一个子目录作为参数传递给 require()
。
The first is to create a package.json
file in the root of the folder,which specifies amain
module. An example package.json file mightlook like this:
第一种方法是在目录的根下创建一个名为package.json
的文件,它指定了一个main
模块。一个package.jso文件的例子如下面所示:
{ "name" : "some-library",
"main" : "./lib/some-library.js" }
If this was in a folder at ./some-library
, thenrequire('./some-library')
would attempt to load./some-library/lib/some-library.js
.
如果此文件位于./some-library
目录中,require('./some-library')
将试图加载文件./some-library/lib/some-library.js
。
This is the extent of Node's awareness of package.json files.
这是Node感知package.json文件的范围。
If there is no package.json file present in the directory, then nodewill attempt to load anindex.js
or index.node
file out of thatdirectory. For example, if there was no package.json file in the aboveexample, thenrequire('./some-library')
would attempt to load:
如果在目录中没有package.json文件,node将试图在该目录中加载index.js
或 index.node
文件。例如,在上面的例子中没有 package.json文件,require('./some-library')
将试图加载:
./some-library/index.js
./some-library/index.node
Caching 缓存
Modules are cached after the first time they are loaded. This means(among other things) that every call torequire('foo')
will getexactly the same object returned, if it would resolve to the same file.
模块在第一次加载后将被缓存。这意味着(类似其他缓存)每次调用require('foo')
如果解析到相同的文件,那么将返回同一个对象。
All Together... 总结一下...
To get the exact filename that will be loaded when require()
is called, usetherequire.resolve()
function.
可使用require.resolve()
函数,获得调用require()
时将加载的准确的文件名。
Putting together all of the above, here is the high-level algorithmin pseudocode of what require.resolve does:
综上所述,这里以伪代码的形式给出require.resolve的算法逻辑:
require(X)
1. If X is a core module,
a. return the core module
b. STOP
2. If X begins with `./` or `/`,
a. LOAD_AS_FILE(Y + X)
b. LOAD_AS_DIRECTORY(Y + X)
3. LOAD_NODE_MODULES(X, dirname(Y))
4. THROW "not found"
LOAD_AS_FILE(X)
1. If X is a file, load X as JavaScript text. STOP
2. If X.js is a file, load X.js as JavaScript text. STOP
3. If X.node is a file, load X.node as binary addon. STOP
LOAD_AS_DIRECTORY(X)
1. If X/package.json is a file,
a. Parse X/package.json, and look for "main" field.
b. let M = X + (json main field)
c. LOAD_AS_FILE(M)
2. LOAD_AS_FILE(X/index)
LOAD_NODE_MODULES(X, START)
1. let DIRS=NODE_MODULES_PATHS(START)
2. for each DIR in DIRS:
a. LOAD_AS_FILE(DIR/X)
b. LOAD_AS_DIRECTORY(DIR/X)
NODE_MODULES_PATHS(START)
1. let PARTS = path split(START)
2. let ROOT = index of first instance of "node_modules" in PARTS, or 0
3. let I = count of PARTS - 1
4. let DIRS = []
5. while I > ROOT,
a. if PARTS[I] = "node_modules" CONTINUE
c. DIR = path join(PARTS[0 .. I] + "node_modules")
b. DIRS = DIRS + DIR
6. return DIRS
Loading from the `require.paths` Folders 从`require.paths`目录中加载
In node, require.paths
is an array of strings that represent paths tobe searched for modules when they are not prefixed with'/'
, './'
, or'../'
. For example, if require.paths were set to:
在node中,require.paths
是一个保存模块搜索路径的字符串数组。当模块不以'/'
,'./'
或'../'
为前缀时,将从此数组中的路径里进行搜索。例如,如果require.paths如下设置:
[ '/home/micheil/.node_modules',
'/usr/local/lib/node_modules' ]
Then calling require('bar/baz.js')
would search the followinglocations:
当调用require('bar/baz.js')
时将搜索下列位置:
- 1:
'/home/micheil/.node_modules/bar/baz.js'
- 2:
'/usr/local/lib/node_modules/bar/baz.js'
The require.paths
array can be mutated at run time to alter thisbehavior.
可以在运行时改变require.paths
数组的内容,以改变路径搜索行为。
It is set initially from the NODE_PATH
environment variable, which isa colon-delimited list of absolute paths. In the previous example,theNODE_PATH
environment variable might have been set to:
此数组使用NODE_PATH
环境变量进行初始化,此环境变量是冒号分割的路径列表。在之前的例子中,NODE_PATH
环境变量被设置为如下内容:
/home/micheil/.node_modules:/usr/local/lib/node_modules
Loading from the require.paths
locations is only performed if themodule could not be found using thenode_modules
algorithm above.Global modules are lower priority than bundled dependencies.
只有当使用上面介绍的node_modules
算法无法找到模块时,才会从require.paths
地址里进行加载。全局模块比绑定抵赖的模块优先级低。
**Note:** Please Avoid Modifying `require.paths` **注意:** 请不要修改`requires.paths`
For compatibility reasons, require.paths
is still given first priorityin the module lookup process. However, it may disappear in a futurerelease.
由于兼容性的原因,require.paths
仍然在模块查询过程中处于第一优先级。然而,在未来发布的版本中这个问题将被解决。
While it seemed like a good idea at the time, and enabled a lot ofuseful experimentation, in practice a mutablerequire.paths
list isoften a troublesome source of confusion and headaches.
虽然在当时看起来这是个好注意,可以支持很多有用的实验手段。但在实践中发现,修改require.paths
列表往往是造成混乱和麻烦的源头。
Setting `require.paths` to some other value does nothing. 将`require.paths`设为其他值不会产生任何作用
This does not do what one might expect:
下述做法不会其他你期望的任何效果:
require.paths = [ '/usr/lib/node' ];
All that does is lose the reference to the actual node module lookuppaths, and create a new reference to some other thing that isn't usedfor anything.
这么做将会丢失对真正的模块搜索路径列表对象的引用,同时指向了一个新创建的对象,而这个对象将不会其任何作用。
Putting relative paths in `require.paths` is... weird. 不建议在`require.paths`中发入相对路径
If you do this:
如果你这样做:
require.paths.push('./lib');
then it does not add the full resolved path to where ./lib
is on the filesystem. Instead, it literally adds'./lib'
,meaning that if you do require('y.js')
in /a/b/x.js
, then it'll lookin /a/b/lib/y.js
. If you then did require('y.js')
in/l/m/n/o/p.js
, then it'd look in /l/m/n/o/lib/y.js
.
这样只会添加'./lib'
字符串到搜索路径列表,而不会解析./lib
在文件系统中的绝对路径。这意味着如果你在/a/b/x.js
中调用require('y.js')
,将找到/a/b/lib/y.js
。而如果你在/l/m/n/o/p.js
中调用require('y.js')
,将找到/l/m/n/o/lib/y.js
。
In practice, people have used this as an ad hoc way to bundledependencies, but this technique is brittle.
在实践中,有用户使用这种特别的方式来实现绑定依赖,但这种方式是很脆弱的。
Zero Isolation 零隔离
There is (by regrettable design), only one require.paths
array used byall modules.
由于设计的失误,所有模块都共享同一个require.paths
数组。
As a result, if one node program comes to rely on this behavior, it maypermanently and subtly alter the behavior of all other node programs inthe same process. As the application stack grows, we tend to assemblefunctionality, and it is a problem with those parts interact in waysthat are difficult to predict.
造成的结果是,如果一个node程序依赖于这种行为,它将永久的并且隐蔽的改变处在同个进程内的所有其他node程序的行为。一旦应用程序变大,我们往往进行功能集成,各部分功能以不可预料的方式互相影响将成为问题。
Addenda: Package Manager Tips 附录:包管理技巧
The semantics of Node's require()
function were designed to be generalenough to support a number of sane directory structures. Package managerprograms such asdpkg
, rpm
, and npm
will hopefully find it possible tobuild native packages from Node modules without modification.
Node的require()
函数的语义被设计的足够通用化,以支持各种常规目录结构。包管理程序如 dpkg
,rpm
和npm
将不用修改就能够从Node模块构建本地包。
Below we give a suggested directory structure that could work:
接下来我们将给你一个可行的目录结构建议:
Let's say that we wanted to have the folder at/usr/lib/node/
hold the contents of aspecific version of a package.
假设我们希望将一个包的指定版本放在/usr/lib/node/
目录中。
Packages can depend on one another. In order to install package foo
, youmay have to install a specific version of packagebar
. The bar
packagemay itself have dependencies, and in some cases, these dependencies may evencollide or form cycles.
包可以依赖于其他包。为了安装包foo
,可能需要安装包bar
的一个指定版本。包bar
也可能有依赖关系,在一些情况下依赖关系可能发生冲突或形成循环。
Since Node looks up the realpath
of any modules it loads (that is,resolves symlinks), and then looks for their dependencies in thenode_modules
folders as described above, this situation is very simple toresolve with the following architecture:
因为Node会查找它所加载的模块的真实路径
(也就是说会解析符号链接),然后按照上文描述的方式在node_modules
目录中寻找依赖关系,所以可以使用如下的目录结构解决这个问题:
/usr/lib/node/foo/1.2.3/
- Contents of thefoo
package, version 1.2.3./usr/lib/node/foo/1.2.3/
- 包foo
的1.2.3版本内容。/usr/lib/node/bar/4.3.2/
- Contents of thebar
package thatfoo
depends on./usr/lib/node/bar/4.3.2/
- 包foo
依赖的包bar
的内容。/usr/lib/node/foo/1.2.3/node_modules/bar
- Symbolic link to/usr/lib/node/bar/4.3.2/
./usr/lib/node/foo/1.2.3/node_modules/bar
- 指向/usr/lib/node/bar/4.3.2/
的符号链接。/usr/lib/node/bar/4.3.2/node_modules/*
- Symbolic links to the packagesthatbar
depends on./usr/lib/node/bar/4.3.2/node_modules/*
- 指向包bar
所依赖的包的符号链接。
Thus, even if a cycle is encountered, or if there are dependencyconflicts, every module will be able to get a version of its dependencythat it can use.
因此即便存在循环依赖或依赖冲突,每个模块还是可以获得他所依赖的包的一个可用版本。
When the code in the foo
package does require('bar')
, it will get theversion that is symlinked into/usr/lib/node/foo/1.2.3/node_modules/bar
.Then, when the code in the bar
package calls require('quux')
, it'll getthe version that is symlinked into/usr/lib/node/bar/4.3.2/node_modules/quux
.
当包foo
中的代码调用require('bar')
,将获得符号链接/usr/lib/node/foo/1.2.3/node_modules/bar
指向的版本。同样,当包bar
中的代码调用require('queue')
,降火的符号链接/usr/lib/node/bar/4.3.2/node_modules/quux
指向的版本。
Furthermore, to make the module lookup process even more optimal, ratherthan putting packages directly in/usr/lib/node
, we could put them in/usr/lib/node_modules/
. Then node will not botherlooking for missing dependencies in/usr/node_modules
or /node_modules
.
为了进一步优化模块搜索过程,不要将包直接放在/usr/lib/node
目录中,而是将它们放在/usr/lib/node_modules/
目录中。这样在依赖的包找不到的情况下,就不会一直寻找到/usr/node_modules
目录或/node_modules
目录中了。
In order to make modules available to the node REPL, it might be useful toalso add the/usr/lib/node_modules
folder to the $NODE_PATH
environmentvariable. Since the module lookups usingnode_modules
folders are allrelative, and based on the real path of the files making the calls torequire()
, the packages themselves can be anywhere.
为了使模块在node REPL中可用,你可能需要将/usr/lib/node_modules
目录加入到$NODE_PATH
环境变量中。由于在node_modules
目录中搜索模块使用的是相对路径,基于调用require()
的文件所在真实路径,因此包本身可以放在任何位置。## Addons 扩展插件
Addons are dynamically linked shared objects. They can provide glue to C andC++ libraries. The API (at the moment) is rather complex, involvingknowledge of several libraries:
扩展插件(Addons)是动态链接的共享对象,这些对象提供了使用C/C++类库的能力。由于涉及了多个类库导致了这类API目前比较繁杂,主要包括下述几个主要类库:
-
V8 JavaScript, a C++ library. Used for interfacing with JavaScript:creating objects, calling functions, etc. Documented mostly in the
v8.h
header file (deps/v8/include/v8.h
in the Node source tree).V8 JavaScript,C++类库,作为JavaScript的接口类,主要用于创建对象、调用方法等功能。大部分功能在头文件
v8.h
(在node文件夹下的路径为deps/v8/include/v8.h
)中有详细文档。 -
libev, C event loop library. Anytime one needs to wait for a filedescriptor to become readable, wait for a timer, or wait for a signal toreceived one will need to interface with libev. That is, if you performany I/O, libev will need to be used. Node uses the
EV_DEFAULT
eventloop. Documentation can be found here.libev,基于C的事件循环库。当需要等待文件描述(file descriptor)为可读时,等待定时器时,或者等待接受信号时,会需要调用libev库。也可以说,任何IO操作都需要调用libev库。Node使用
EV_DEFAULT
事件循环机制。在这里可以查阅相关文档。 -
libeio, C thread pool library. Used to execute blocking POSIX systemcalls asynchronously. Mostly wrappers already exist for such calls, in
src/file.cc
so you will probably not need to use it. If you do need it,look at the header filedeps/libeio/eio.h
.libeio,基于C的线程池库,用于以异步方式执行阻塞式POSIX系统调用。因为大部分这类调用都在
src/file.cc
中被封装了,你一般不需要直接使用libeio。如果必须使用该类库时,可查看其头文件deps/libeio/eio.h
。 -
Internal Node libraries. Most importantly is the
node::ObjectWrap
class which you will likely want to derive from.内部Node库。在该库中,最重要的类是我们可能用于进行派生的
node::ObjectWrap
基类。 -
Others. Look in
deps/
for what else is available.其他的一些类库同样可以在
deps/
中找到。
Node statically compiles all its dependencies into the executable. Whencompiling your module, you don't need to worry about linking to any of theselibraries.
Node已将所有依赖关系静态地编译成可执行文件,因此我们在编译自己的组件时不需要担心和这些类库的链接问题。
To get started let's make a small Addon which does the following except inC++:
让我们着手编写一个Addon的小例子,来达到如下模块同样的效果:
exports.hello = 'world';
To get started we create a file hello.cc
:
首先我们需要创建一个hello.cc
文件:
#include <v8.h>
using namespace v8;
extern "C" void
init (Handle<Object> target)
{
HandleScope scope;
target->Set(String::New("hello"), String::New("world"));
}
This source code needs to be built into hello.node
, the binary Addon. Todo this we create a file calledwscript
which is python code and lookslike this:
这些源码会编译成一个二进制的Addon文件hello.node
。为此我们用python编写如下的名为wscript
的文件:
srcdir = '.'
blddir = 'build'
VERSION = '0.0.1'
def set_options(opt):
opt.tool_options('compiler_cxx')
def configure(conf):
conf.check_tool('compiler_cxx')
conf.check_tool('node_addon')
def build(bld):
obj = bld.new_task_gen('cxx', 'shlib', 'node_addon')
obj.target = 'hello'
obj.source = 'hello.cc'
Running node-waf configure build
will create a filebuild/default/hello.node
which is our Addon.
运行node-waf configure build
,我们就创建了一个Addon实例build/default/hello.node
。
node-waf
is just WAF, the python-based build system.node-waf
isprovided for the ease of users.
node-waf
就是WAF,,一种基于python的编译系统,而node-waf
更加易于使用。
All Node addons must export a function called init
with this signature:
另外,在Node中任何的Addon必须使用输出一个如下声明的init
函数:
extern 'C' void init (Handle<Object> target)
For the moment, that is all the documentation on addons. Please seehttp://github.com/ry/node_postgres for a real example.
目前关于addon的所有文档就是这些。另外,在http://github.com/ry/node_postgres中还提供了一个Addon的实例。## process 进程
The process
object is a global object and can be accessed from anywhere.
process
对象是一个全局对象,可以在任何地方访问它。
It is an instance of EventEmitter
.
它是EventEmitter
事件触发器类型的一个实例。
Event: 'exit' 事件:'exit'
function () {}
Emitted when the process is about to exit. This is a good hook to performconstant time checks of the module's state (like for unit tests). The mainevent loop will no longer be run after the 'exit' callback finishes, sotimers may not be scheduled.
当进程对象要退出时会触发此方法,这是检查模块状态(比如单元测试)的好时机。当'exit'被调用完成后主事件循环将终止,所以计时器将不会按计划执行。
Example of listening for exit
:
监听exit
行为的示例:
process.on('exit', function () {
process.nextTick(function () {
console.log('This will not run');
});
console.log('About to exit.');
});
Event: 'uncaughtException' 事件:'uncaughtException'
function (err) { }
Emitted when an exception bubbles all the way back to the event loop. If alistener is added for this exception, the default action (which is to printa stack trace and exit) will not occur.
当一个异常信息一路冒出到事件循环时,该方法被触发。如果该异常有一个监听器,那么默认的行为(即打印一个堆栈轨迹并退出)将不会发生。
Example of listening for uncaughtException
:
监听uncaughtException
事件的示例:
process.on('uncaughtException', function (err) {
console.log('Caught exception: ' + err);
});
setTimeout(function () {
console.log('This will still run.');
}, 500);
// Intentionally cause an exception, but don't catch it.
nonexistentFunc();
console.log('This will not run.');
Note that uncaughtException
is a very crude mechanism for exceptionhandling. Using try / catch in your program will give you more control overyour program's flow. Especially for server programs that are designed tostay running forever,uncaughtException
can be a useful safety mechanism.
注意:就异常处理来说,uncaughtException
是一个很粗糙的机制。在程序中使用try/catch可以更好好控制程序流程。而在服务器编程中,因为要持续运行,uncaughtException
还是一个很有用的安全机制。
Signal Events 信号事件
function () {}
Emitted when the processes receives a signal. See sigaction(2) for a list ofstandard POSIX signal names such as SIGINT, SIGUSR1, etc.
该事件会在进程接收到一个信号时被触发。可参见sigaction(2)中的标准POSIX信号名称列表,比如SIGINT,SIGUSR1等等。
Example of listening for SIGINT
:
监听 SIGINT
的示例:
// Start reading from stdin so we don't exit.
process.stdin.resume();
process.on('SIGINT', function () {
console.log('Got SIGINT. Press Control-D to exit.');
});
An easy way to send the SIGINT
signal is with Control-C
in most terminalprograms.
在大多数终端程序中,一个简易发送SIGINT
信号的方法是在使用Control-C
命令操作。
process.stdout
A Writable Stream
to stdout
.
一个指向标准输出stdout
的Writable Stream
可写流。
Example: the definition of console.log
示例:console.log
的定义。
console.log = function (d) {
process.stdout.write(d + '\n');
};
process.stderr
A writable stream to stderr. Writes on this stream are blocking.
一个指向错误的可写流,在这个流上的写操作是阻塞式的。
process.stdin
A Readable Stream
for stdin. The stdin stream is paused by default, so onemust callprocess.stdin.resume()
to read from it.
一个到标准输入的可读流Readable Stream
。默认情况下标准输入流是暂停的,要从中读取内容需要调用方法process.stdin.resume()
。
Example of opening standard input and listening for both events:
示例:打开标准输入与监听两个事件:
process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data', function (chunk) {
process.stdout.write('data: ' + chunk);
});
process.stdin.on('end', function () {
process.stdout.write('end');
});
process.argv
An array containing the command line arguments. The first element will be'node', the second element will be the name of the JavaScript file. Thenext elements will be any additional command line arguments.
一个包含命令行参数的数组。第一个元素是'node',第二个元素是JavaScript文件的文件名。接下来的元素则是附加的命令行参数。
// print process.argv
process.argv.forEach(function (val, index, array) {
console.log(index + ': ' + val);
});
This will generate:
这产生如下的信息:
$ node process-2.js one two=three four
0: node
1: /Users/mjr/work/node/process-2.js
2: one
3: two=three
4: four
process.execPath
This is the absolute pathname of the executable that started the process.
这是一个启动该进程的可执行程序的绝对路径名。
Example:
例如:
/usr/local/bin/node
process.chdir(directory)
Changes the current working directory of the process or throws an exception if that fails.
改变进程的当前工作目录,如果操作失败则抛出异常。
console.log('Starting directory: ' + process.cwd());
try {
process.chdir('/tmp');
console.log('New directory: ' + process.cwd());
}
catch (err) {
console.log('chdir: ' + err);
}
process.cwd()
Returns the current working directory of the process.
返回进程的当前工作目录。
console.log('Current directory: ' + process.cwd());
process.env
An object containing the user environment. See environ(7).
一个包括用户环境的对象。可参见environ(7)。
process.exit(code=0)
Ends the process with the specified code
. If omitted, exit uses the'success' code0
.
用指定的code
代码结束进程。如果不指定,退出时将使用'success'(成功)代码 0
。
To exit with a 'failure' code:
以'failure'(失败)代码退出的示例:
process.exit(1);
The shell that executed node should see the exit code as 1.
执行node的shell会把退出代码视为1。
process.getgid()
Gets the group identity of the process. (See getgid(2).)This is the numerical group id, not the group name.
获取进程的群组标识(详见getgid(2))。这是一个数字的群组ID,不是群组名称。
console.log('Current gid: ' + process.getgid());
process.setgid(id)
Sets the group identity of the process. (See setgid(2).) This accepts eithera numerical ID or a groupname string. If a groupname is specified, this methodblocks while resolving it to a numerical ID.
设置进程的群组标识(详见getgid(2))。参数可以是一个数字ID或者群组名字符串。如果指定了一个群组名,这个方法会阻塞等待将群组名解析为数字ID。
console.log('Current gid: ' + process.getgid());
try {
process.setgid(501);
console.log('New gid: ' + process.getgid());
}
catch (err) {
console.log('Failed to set gid: ' + err);
}
process.getuid()
Gets the user identity of the process. (See getuid(2).)This is the numerical userid, not the username.
获取进程的用户ID(详见getgid(2))。这是一个数字用户ID,不是用户名。
console.log('Current uid: ' + process.getuid());
process.setuid(id)
Sets the user identity of the process. (See setuid(2).) This accepts eithera numerical ID or a username string. If a username is specified, this methodblocks while resolving it to a numerical ID.
设置进程的用户ID(详见getgid(2))。参数可以使一个数字ID或者用户名字符串。如果指定了一个用户名,那么该方法会阻塞等待将用户名解析为数字ID。
console.log('Current uid: ' + process.getuid());
try {
process.setuid(501);
console.log('New uid: ' + process.getuid());
}
catch (err) {
console.log('Failed to set uid: ' + err);
}
process.version
A compiled-in property that exposes NODE_VERSION
.
一个编译内置的属性,用于显示NODE_VERSION
(Node版本)。
console.log('Version: ' + process.version);
process.installPrefix
A compiled-in property that exposes NODE_PREFIX
.
一个编译内置的属性,用于显示NODE_PREFIX
(Node安装路径前缀)。
console.log('Prefix: ' + process.installPrefix);
process.kill(pid, signal='SIGTERM')
Send a signal to a process. pid
is the process id and signal
is thestring describing the signal to send. Signal names are strings like'SIGINT' or 'SIGUSR1'. If omitted, the signal will be 'SIGTERM'.See kill(2) for more information.
发送一个信号到进程。pid
是进程的ID,参数signal
是欲发送信号的字符串描述。信号名称是像'SIGINT'或者'SIGUSR1'这样的字符串。如果参数signal
忽略,则信号为'SIGTERM'。详见kill(2)。
Note that just because the name of this function is process.kill
, it isreally just a signal sender, like thekill
system call. The signal sentmay do something other than kill the target process.
注意该函数名为process.kill
,实际上也就像kill
系统调用一样仅仅是一个信号发送器。发送的信号可能是要终止目标进程,也可能是实现其他不同的目的。
Example of sending a signal to yourself:
一个给自己发送信号的示例:
process.on('SIGHUP', function () {
console.log('Got SIGHUP signal.');
});
setTimeout(function () {
console.log('Exiting.');
process.exit(0);
}, 100);
process.kill(process.pid, 'SIGHUP');
process.pid
The PID of the process.
进程的PID。
console.log('This process is pid ' + process.pid);
process.title
Getter/setter to set what is displayed in 'ps'.
获取或设置在'ps'命令中显示的进程的标题。
process.platform
What platform you're running on. 'linux2'
, 'darwin'
, etc.
运行Node的平台信息,如'linux2',
'darwin'`等等。
console.log('This platform is ' + process.platform);
process.memoryUsage()
Returns an object describing the memory usage of the Node process.
返回一个描述Node进程内存使用情况的对象。
var util = require('util');
console.log(util.inspect(process.memoryUsage()));
This will generate:
这会生成如下信息:
{ rss: 4935680,
vsize: 41893888,
heapTotal: 1826816,
heapUsed: 650472 }
heapTotal
and heapUsed
refer to V8's memory usage.
heapTotal
与heapUsed
指V8的内存使用情况。
process.nextTick(callback)
On the next loop around the event loop call this callback.This is not a simple alias tosetTimeout(fn, 0)
, it's much moreefficient.
在事件循环的下一次循环中调用callback回调函数。这不是setTimeout(fn, 0)
的一个别名,因为它有效率多了。
process.nextTick(function () {
console.log('nextTick callback');
});
process.umask([mask])
Sets or reads the process's file mode creation mask. Child processes inheritthe mask from the parent process. Returns the old mask ifmask
argument isgiven, otherwise returns the current mask.
设置或者读取进程的文件模式创建掩码。子进程从父进程中继承这个掩码。如果设定了参数mask
那么返回旧的掩码,否则返回当前的掩码。
var oldmask, newmask = 0644;
oldmask = process.umask(newmask);
console.log('Changed umask from: ' + oldmask.toString(8) +
' to ' + newmask.toString(8));
util 工具模块
These functions are in the module 'util'
. Use require('util')
to accessthem.
下列函数属于'util'
(工具)模块,可使用require('util')
访问它们。
util.debug(string)
A synchronous output function. Will block the process andoutput string
immediately tostderr
.
这是一个同步输出函数,将string
参数的内容实时输出到stderr
标准错误。调用此函数时将阻塞当前进程直到输出完成。
require('util').debug('message on stderr');
util.log(string)
Output with timestamp on stdout
.
将string
参数的内容加上当前时间戳,输出到stdout
标准输出。
require('util').log('Timestmaped message.');
util.inspect(object, showHidden=false, depth=2)
Return a string representation of object
, which is useful for debugging.
以字符串形式返回object
对象的结构信息,这对程序调试非常有帮助。
If showHidden
is true
, then the object's non-enumerable properties will beshown too.
如果showHidden
参数设置为true
,则此对象的不可枚举属性也会被显示。
If depth
is provided, it tells inspect
how many times to recurse whileformatting the object. This is useful for inspecting large complicated objects.
可使用depth
参数指定inspect
函数在格式化对象信息时的递归次数。这对分析复杂对象的内部结构非常有帮助。
The default is to only recurse twice. To make it recurse indefinitely, passin null
for depth
.
默认情况下递归两次,如果想要无限递归可将depth
参数设为null
。
Example of inspecting all properties of the util
object:
显示util
对象所有属性的例子如下:
var util = require('util');
console.log(util.inspect(util, true, null));
util.pump(readableStream, writableStream, [callback])
Experimental
实验性的
Read the data from readableStream
and send it to the writableStream
.WhenwritableStream.write(data)
returns false
readableStream
will bepaused until thedrain
event occurs on the writableStream
. callback
getsan error as its only argument and is called whenwritableStream
is closed orwhen an error occurs.
从readableStream
参数所指定的可读流中读取数据,并将其写入到writableStream
参数所指定的可写流中。当writeableStream.write(data)
函数调用返回为false
时,readableStream
流将被暂停,直到在writableStream
流上发生drain
事件。当writableStream
流被关闭或发生一个错误时,callback
回调函数被调用。此回调函数只接受一个参数用以指明所发生的错误。
util.inherits(constructor, superConstructor)
Inherit the prototype methods from oneconstructorinto another. The prototype ofconstructor
will be set to a newobject created from superConstructor
.
将一个构造函数的原型方法继承到另一个构造函数中。constructor
构造函数的原型将被设置为使用superConstructor
构造函数所创建的一个新对象。
As an additional convenience, superConstructor
will be accessiblethrough theconstructor.super_
property.
此方法带来的额外的好处是,可以通过constructor.super_
属性来访问superConstructor
构造函数。
var util = require("util");
var events = require("events");
function MyStream() {
events.EventEmitter.call(this);
}
util.inherits(MyStream, events.EventEmitter);
MyStream.prototype.write = function(data) {
this.emit("data", data);
}
var stream = new MyStream();
console.log(stream instanceof events.EventEmitter); // true
console.log(MyStream.super_ === events.EventEmitter); // true
stream.on("data", function(data) {
console.log('Received data: "' + data + '"');
})
stream.write("It works!"); // Received data: "It works!"
Events 事件模块
Many objects in Node emit events: a net.Server
emits an event each timea peer connects to it, afs.readStream
emits an event when the file isopened. All objects which emit events are instances ofevents.EventEmitter
.You can access this module by doing: require("events");
Node引擎中很多对象都会触发事件:例如net.Server
会在每一次有客户端连接到它时触发事件,又如fs.readStream
会在文件打开时触发事件。所有能够触发事件的对象都是events.EventEmitter
的实例。你可以通过require("events");
访问这个模块。
Typically, event names are represented by a camel-cased string, however,there aren't any strict restrictions on that, as any string will be accepted.
通常情况下,事件名称采用驼峰式写法,不过目前并没有对事件名称作任何的限制,也就是说任何的字符串都可以被接受。
Functions can then be attached to objects, to be executed when an eventis emitted. These functions are calledlisteners.
可以将函数注册给对象,使其在事件触发时执行,此类函数被称作监听器。
events.EventEmitter
To access the EventEmitter class, require('events').EventEmitter
.
通过调用require('events').EventEmitter
,我们可以使用事件触发器类。
When an EventEmitter
instance experiences an error, the typical action isto emit an'error'
event. Error events are treated as a special case in node.If there is no listener for it, then the default action is to print a stacktrace and exit the program.
当EventEmitter
事件触发器遇到错误时,典型的处理方式是它将触发一个'error'
事件。Error事件的特殊性在于:如果没有函数处理这个事件,它将会输出调用堆栈,并随之退出应用程序。
All EventEmitters emit the event 'newListener'
when new listeners areadded.
当新的事件监听器被添加时,所有的事件触发器都将触发名为'newListener'
的事件。
emitter.addListener(event, listener)
emitter.on(event, listener)
Adds a listener to the end of the listeners array for the specified event.
将一个监听器添加到指定事件的监听器数组的末尾。
server.on('connection', function (stream) {
console.log('someone connected!');
});
emitter.once(event, listener)
Adds a one time listener for the event. The listener isinvoked only the first time the event is fired, after whichit is removed.
为事件添加一次性的监听器。该监听器在事件第一次触发时执行,过后将被移除。
server.once('connection', function (stream) {
console.log('Ah, we have our first user!');
});
emitter.removeListener(event, listener)
Remove a listener from the listener array for the specified event.Caution: changes array indices in the listener array behind the listener.
将监听器从指定事件的监听器数组中移除出去。小心:此操作将改变监听器数组的下标。
var callback = function(stream) {
console.log('someone connected!');
};
server.on('connection', callback);
// ...
server.removeListener('connection', callback);
emitter.removeAllListeners(event)
Removes all listeners from the listener array for the specified event.
将指定事件的所有监听器从监听器数组中移除。
emitter.setMaxListeners(n)
By default EventEmitters will print a warning if more than 10 listeners areadded to it. This is a useful default which helps finding memory leaks.Obviously not all Emitters should be limited to 10. This function allowsthat to be increased. Set to zero for unlimited.
默认情况下当事件触发器注册了超过10个以上的监听器时系统会打印警告信息,这个默认配置将有助于你查找内存泄露问题。很显然并不是所有的事件触发器都需要进行10个监听器的限制,此函数允许你手动设置该数量值,如果值为0意味值没有限制。
emitter.listeners(event)
Returns an array of listeners for the specified event. This array can bemanipulated, e.g. to remove listeners.
返回指定事件的监听器数组对象,你可以对该数组进行操作,比如说删除监听器等。
server.on('connection', function (stream) {
console.log('someone connected!');
});
console.log(util.inspect(server.listeners('connection')); // [ [Function] ]
emitter.emit(event, [arg1], [arg2], [...])
Execute each of the listeners in order with the supplied arguments.
以提供的参数作为监听器函数的参数,顺序执行监听器列表中的每个监听器函数。
Event: 'newListener' 事件:'newListener'
function (event, listener) { }
This event is emitted any time someone adds a new listener.
任何时候只要新的监听器被添加时该事件就会触发。
Buffers 缓冲器
Pure Javascript is Unicode friendly but not nice to binary data. Whendealing with TCP streams or the file system, it's necessary to handle octetstreams. Node has several strategies for manipulating, creating, andconsuming octet streams.
纯Javascript语言是Unicode友好性的,但是难以处理二进制数据。在处理TCP流和文件系统时经常需要操作字节流。Node提供了一些列机制,用于操作、创建、以及消耗(consuming)字节流。
Raw data is stored in instances of the Buffer
class. A Buffer
is similarto an array of integers but corresponds to a raw memory allocation outsidethe V8 heap. ABuffer
cannot be resized.
在实例化的Buffer
类中存储了原始数据。Buffer
类似于一个整数数组,但Buffer
对应了在V8堆(the V8 heap)外的原始存储空间分配。一旦创建了Buffer
实例,则无法改变其大小。
The Buffer
object is global.
另外,Buffer
是一个全局对象。
Converting between Buffers and JavaScript string objects requires an explicit encodingmethod. Here are the different string encodings;
在缓冲器(Buffers)和JavaScript间进行字符串的转换需要调用特定的编码方法。如下列举了不同的编码方法:
-
'ascii'
- for 7 bit ASCII data only. This encoding method is very fast, and willstrip the high bit if set.'ascii'
- 仅对应7位的ASCII数据。虽然这种编码方式非常迅速,并且如果设置了最高位,则会将其移去。 -
'utf8'
- Multi byte encoded Unicode characters. Many web pages and other document formats use UTF-8.'utf8'
- 对应多字节编码Unicode字符。大量网页和其他文件格式使用这类编码方式。 -
'ucs2'
- 2-bytes, little endian encoded Unicode characters. It can encodeonly BMP(Basic Multilingual Plane, U+0000 - U+FFFF).'ucs2'
- 2字节的,低字节序编码Unicode字符。只能编码BMP(第零平面,U+0000 - U+FFFF)字符。 -
'base64'
- Base64 string encoding.'base64'
- Base64 字符串编码. -
'binary'
- A way of encoding raw binary data into strings by using onlythe first 8 bits of each character. This encoding method is depreciated andshould be avoided in favor ofBuffer
objects where possible. This encodingwill be removed in future versions of Node.'binary'
- 仅使用每个字符的头8位将原始的二进制信息进行编码。在需使用Buffer
的情况下,应该尽量避免使用这个已经过时的编码方式。而且,这个编码方式不会出现在未来版本的Node中。 -
'hex'
- Encode each byte as two hexidecimal characters.'hex'
- 将一个字节编码为两个16进制字符。
new Buffer(size)
Allocates a new buffer of size
octets.
分配给一个新创建的buffer实例一个大小为size
字节的空间。
new Buffer(array)
Allocates a new buffer using an array
of octets.
使用array
的空间创建一个buffer实例。
new Buffer(str, encoding='utf8')
Allocates a new buffer containing the given str
.
创建一个包含给定str
的buffer实例。
buffer.write(string, offset=0, encoding='utf8')
Writes string
to the buffer at offset
using the given encoding. Returnsnumber of octets written. Ifbuffer
did not contain enough space to fitthe entire string, it will write a partial amount of the string. In the caseof'utf8'
encoding, the method will not write partial characters.
通过给定的编码方式把string
写入到buffer的offset
(偏移地址)中,并且返回写入的字节数。如果当前的buffer
没有足够存储空间,字符串会部分地保存在buffer
中,而不是整串字符。需要注意的是,如果使用'utf8'
进行编码,该方法不会对零散的字符进行编写。
Example: write a utf8 string into a buffer, then print it
例如:将一串utf8格式的字符串写入Buffer,然后输出:
buf = new Buffer(256);
len = buf.write('\u00bd + \u00bc = \u00be', 0);
console.log(len + " bytes: " + buf.toString('utf8', 0, len));
// 12 bytes: ½ + ¼ = ¾
buffer.toString(encoding, start=0, end=buffer.length)
Decodes and returns a string from buffer data encoded with encoding
beginning atstart
and ending at end
.
对缓冲器中的以encoding
方式编码的,以start
标识符开始,以end
标识符结尾的缓冲数据进行解码,并输出字符串。
See buffer.write()
example, above.
参见上文的buffer.write()
例子。
buffer[index]
Get and set the octet at index
. The values refer to individual bytes,so the legal range is between0x00
and 0xFF
hex or 0
and 255
.
获取或者设置位于index
字节的值。由于返回值为单个的字节,因此其范围应该在0x00
到 0xFF
(16进制)或者0
and255
(10进制)之间
Example: copy an ASCII string into a buffer, one byte at a time:
例如:通过每次仅输入一个字符的方式将整串ASCII字符录入Buffer中:
str = "node.js";
buf = new Buffer(str.length);
for (var i = 0; i < str.length ; i++) {
buf[i] = str.charCodeAt(i);
}
console.log(buf);
// node.js
Buffer.isBuffer(obj)
Tests if obj
is a Buffer
.
验证obj
的类别是否为Buffer
类。
Buffer.byteLength(string, encoding='utf8')
Gives the actual byte length of a string. This is not the same asString.prototype.length
since that returns the number ofcharacters in astring.
返回字符串长度的实际值。与String.prototype.length
的区别之处在于该方法返回的是字符串中characters的个数。
Example:
例如:
str = '\u00bd + \u00bc = \u00be';
console.log(str + ": " + str.length + " characters, " +
Buffer.byteLength(str, 'utf8') + " bytes");
// ½ + ¼ = ¾: 9 characters, 12 bytes
buffer.length
The size of the buffer in bytes. Note that this is not necessarily the sizeof the contents.length
refers to the amount of memory allocated for thebuffer object. It does not change when the contents of the buffer are changed.
返回Buffer占用的字节数。需要注意的是,length
并非其内容占的大小,而是指分配给Buffer实例的存储空间的大小,因此该值不会随Buffer内容的变化而变化。
buf = new Buffer(1234);
console.log(buf.length);
buf.write("some string", "ascii", 0);
console.log(buf.length);
// 1234
// 1234
buffer.copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
Does a memcpy() between buffers.
在两个Buffer之间进行memcpy() 操作。
Example: build two Buffers, then copy buf1
from byte 16 through byte 19intobuf2
, starting at the 8th byte in buf2
.
例如:创建2个Buffer实例,然后将buf1
中第16字节到第19字节间的信息复制到buf2
中,并使在buf2
中新的字符串首字符位于第8字节:
buf1 = new Buffer(26);
buf2 = new Buffer(26);
for (var i = 0 ; i < 26 ; i++) {
buf1[i] = i + 97; // 97 is ASCII a
buf2[i] = 33; // ASCII !
}
buf1.copy(buf2, 8, 16, 20);
console.log(buf2.toString('ascii', 0, 25));
// !!!!!!!!qrst!!!!!!!!!!!!!
buffer.slice(start, end=buffer.length)
Returns a new buffer which references thesame memory as the old, but offset and cropped by thestart
and end
indexes.
返回一个和原Buffer引用相同存储空间的新Buffer,但是新Buffer中的偏移地址截取了原Buffer偏移地址中自start
到end
的部分。
Modifying the new buffer slice will modify memory in the original buffer!
特别注意:通过修改新的Buffer切片(slice)中的内容同样会修改存储在原Buffer中的信息!
Example: build a Buffer with the ASCII alphabet, take a slice, then modify one bytefrom the original Buffer.
例如:建立一个ASCII码型的字母表,再建立一个切片,并在原Buffer中修改一个字节:
var buf1 = new Buffer(26);
for (var i = 0 ; i < 26 ; i++) {
buf1[i] = i + 97; // 97 is ASCII a
}
var buf2 = buf1.slice(0, 3);
console.log(buf2.toString('ascii', 0, buf2.length));
buf1[0] = 33;
console.log(buf2.toString('ascii', 0, buf2.length));
// abc
// !bc
Streams 流
A stream is an abstract interface implemented by various objects in Node.For example a request to an HTTP server is a stream, as is stdout. Streamsare readable, writable, or both. All streams are instances ofEventEmitter
.
在Node中,Stream(流)是一个由不同对象实现的抽象接口。例如请求HTTP服务器的request是一个流,类似于stdout(标准输出)。流可以是可读的,可写的,或者既可读又可写。所有流都是EventEmitter
的实例。
Readable Stream 可读流
A Readable Stream
has the following methods, members, and events.
一个可读流
具有下述的方法、成员、及事件。
Event: 'data' 事件:'data'
function (data) { }
The 'data'
event emits either a Buffer
(by default) or a string ifsetEncoding()
was used.
'data'
事件的回调函数参数默认情况下是一个Buffer
对象。如果使用了setEncoding()
则参数为一个字符串。
Event: 'end' 事件:'end'
function () { }
Emitted when the stream has received an EOF (FIN in TCP terminology).Indicates that no more'data'
events will happen. If the stream is alsowritable, it may be possible to continue writing.
当流中接收到EOF(TCP中为FIN)时此事件被触发,表示流的读取已经结束,不会再发生任何'data'
事件。如果流同时也是可写的,那它还可以继续写入。
Event: 'error' 事件:'error'
function (exception) { }
Emitted if there was an error receiving data.
接收数据的过程中发生任何错误时,此事件被触发。
Event: 'close' 事件:'close'
function () { }
Emitted when the underlying file descriptor has been closed. Not all streamswill emit this. (For example, an incoming HTTP request will not emit'close'
.)
当底层的文件描述符被关闭时触发此事件,并不是所有流都会触发这个事件。(例如,一个连接进入的HTTP request流就不会触发'close'
事件。)
Event: 'fd' 事件:'fd'
function (fd) { }
Emitted when a file descriptor is received on the stream. Only UNIX streamssupport this functionality; all others will simply never emit this event.
当在流中接收到一个文件描述符时触发此事件。只有UNIX流支持这个功能,其他类型的流均不会触发此事件。
stream.readable
A boolean that is true
by default, but turns false
after an'error'
occurred, the stream came to an 'end'
, or destroy()
was called.
这是一个布尔值,默认值为true
。当'error'
事件或'end'
事件发生后,或者destroy()
被调用后,这个属性将变为false
。
stream.setEncoding(encoding)
Makes the data event emit a string instead of a Buffer
. encoding
can be'utf8'
,'ascii'
, or 'base64'
.
调用此方法会影响'data'
事件的回调函数参数形式,默认为Buffer
对象,调用此方法后为字符串。encoding
参数可以是'utf8'
、'ascii'
、或'base64'
。
stream.pause()
Pauses the incoming 'data'
events.
暂停'data'
事件的触发。
stream.resume()
Resumes the incoming 'data'
events after a pause()
.
恢复被pause()
调用暂停的'data'
事件触发。
stream.destroy()
Closes the underlying file descriptor. Stream will not emit any more events.
关闭底层的文件描述符。流上将不会再触发任何事件。
stream.destroySoon()
After the write queue is drained, close the file descriptor.
在写队列清空后(所有写操作完成后),关闭文件描述符。
stream.pipe(destination, [options])
This is a Stream.prototype
method available on all Stream
s.
这是Stream.prototype
(Stream原型对象)的一个方法,对所有Stream
对象有效。
Connects this read stream to destination
WriteStream. Incomingdata on this stream gets written todestination
. The destination and sourcestreams are kept in sync by pausing and resuming as necessary.
用于将这个可读流和destination
目标可写流连接起来,传入这个流中的数据将会写入到destination
流中。通过在必要时暂停和恢复流,来源流和目的流得以保持同步。
Emulating the Unix cat
command:
模拟Unix系统的cat
命令:
process.stdin.resume();
process.stdin.pipe(process.stdout);
By default end()
is called on the destination when the source stream emitsend
, so thatdestination
is no longer writable. Pass { end: false }
asoptions
to keep the destination stream open.
默认情况下,当来源流的end
事件触发时目的流的end()
方法会被调用,此时destination
目的流将不再可写入。要在这种情况下为了保持目的流仍然可写入,可将options
参数设为{ end: false }
。
This keeps process.stdout
open so that "Goodbye" can be written at the end.
这使process.stdout
保持打开状态,因此"Goodbye"可以在end事件发生后被写入。
process.stdin.resume();
process.stdin.pipe(process.stdout, { end: false });
process.stdin.on("end", function() {
process.stdout.write("Goodbye\n");
});
NOTE: If the source stream does not support pause()
and resume()
, this functionadds simple definitions which simply emit'pause'
and 'resume'
events onthe source stream.
注意:如果来源流不支持pause()
和resume()
方法,此函数将在来源流对象上增加这两个方法的简单定义,内容为触发'pause'
和'resume'
事件。
Writable Stream 可写流
A Writable Stream
has the following methods, members, and events.
一个可写流
具有下列方法、成员、和事件。
Event: 'drain' 事件:'drain'
function () { }
Emitted after a write()
method was called that returned false
toindicate that it is safe to write again.
发生在write()
方法被调用并返回false
之后。此事件被触发说明内核缓冲区已空,再次写入是安全的。
Event: 'error' 事件:'error'
function (exception) { }
Emitted on error with the exception exception
.
发生错误时被触发,回调函数接收一个异常参数exception
。
Event: 'close' 事件:'close'
function () { }
Emitted when the underlying file descriptor has been closed.
底层文件描述符被关闭时被触发。
Event: 'pipe' 事件:'pipe'
function (src) { }
Emitted when the stream is passed to a readable stream's pipe method.
当此可写流作为参数传给一个可读流的pipe方法时被触发。
stream.writable
A boolean that is true
by default, but turns false
after an'error'
occurred or end()
/ destroy()
was called.
一个布尔值,默认值为true
。在'error'
事件被触发之后,或end()
/destroy()
方法被调用后此属性被设为false
。
stream.write(string, encoding='utf8', [fd])
Writes string
with the given encoding
to the stream. Returnstrue
ifthe string has been flushed to the kernel buffer. Returns false
toindicate that the kernel buffer is full, and the data will be sent out inthe future. The'drain'
event will indicate when the kernel buffer isempty again. Theencoding
defaults to 'utf8'
.
使用指定编码encoding
将字符串string
写入到流中。如果字符串被成功写入内核缓冲区,此方法返回true
。如果内核缓冲区已满,此方法返回false
,数据将在以后被送出。当内核缓冲区再次被清空后'drain'事件将被触发。
encoding参数默认为
'utf8'`。
If the optional fd
parameter is specified, it is interpreted as an integralfile descriptor to be sent over the stream. This is only supported for UNIXstreams, and is silently ignored otherwise. When writing a file descriptor inthis manner, closing the descriptor before the stream drains risks sending aninvalid (closed) FD.
如果指定了可选参数fd
,它将被作为一个文件描述符通过流传送。此功能仅被Unix流所支持,对于其他流此操作将被忽略而没有任何提示。当使用此方法传送一个文件描述符时,如果在流没有清空前关闭此文件描述符,将造成传送一个无效(已关闭)FD的风险。
stream.write(buffer)
Same as the above except with a raw buffer.
除了用一个Buffer对象替代字符串之外,其他同上。
stream.end()
Terminates the stream with EOF or FIN.
使用EOF或FIN结束一个流的输出。
stream.end(string, encoding)
Sends string
with the given encoding
and terminates the stream with EOFor FIN. This is useful to reduce the number of packets sent.
以指定的字符编码encoding
传送一个字符串string
,然后使用EOF或FIN结束流的输出。这对降低数据包传输量有所帮助。
stream.end(buffer)
Same as above but with a buffer
.
除了用一个buffer
对象替代字符串之外,其他同上。
stream.destroy()
Closes the underlying file descriptor. Stream will not emit any more events.
关闭底层文件描述符。在此流上将不会再触发任何事件。
Crypto 加密模块
Use require('crypto')
to access this module.
使用require('crypto')
调用加密模块。
The crypto module requires OpenSSL to be available on the underlying platform.It offers a way of encapsulating secure credentials to be used as partof a secure HTTPS net or http connection.
加密模块需要底层系统提供OpenSSL的支持。它提供了一种安全凭证的封装方式,可以用于HTTPS安全网络以及普通HTTP连接。
It also offers a set of wrappers for OpenSSL's hash, hmac, cipher, decipher, sign and verify methods.
该模块还提供了一套针对OpenSSL的hash(哈希),hmac(密钥哈希),cipher(编码),decipher(解码),sign(签名)以及verify(验证)等方法的封装。
crypto.createCredentials(details)
Creates a credentials object, with the optional details being a dictionary with keys:
创建一个凭证对象,可选参数details为一个带键值的字典:
-
key
: a string holding the PEM encoded private keykey
:为字符串型,PEM编码的私钥。 -
cert
: a string holding the PEM encoded certificatecert
:为字符串型,PEM编码的认证证书。 -
ca
: either a string or list of strings of PEM encoded CA certificates to trust.ca
:字符串形式的PEM编码可信CA证书,或证书列表。
If no 'ca' details are given, then node.js will use the default publicly trusted list of CAs as given inhttp://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt.
如果没有给出'ca'的详细内容,那么node.js将会使用默认的公开受信任列表,该表位于http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt。
crypto.createHash(algorithm)
Creates and returns a hash object, a cryptographic hash with the given algorithmwhich can be used to generate hash digests.
创建并返回一个hash对象,它是一个指定算法的加密hash,用于生成hash摘要。
algorithm
is dependent on the available algorithms supported by the versionof OpenSSL on the platform. Examples are'sha1'
, 'md5'
, 'sha256'
, 'sha512'
, etc.On recent releases,openssl list-message-digest-algorithms
will display the available digest algorithms.
参数algorithm
可选择系统上安装的OpenSSL版本所支持的算法。例如:'sha1'
, 'md5'
, 'sha256'
, 'sha512'
等。在近期发行的版本中,openssl list-message-digest-algorithms
会显示这些可用的摘要算法。
hash.update(data)
Updates the hash content with the given data
.This can be called many times with new data as it is streamed.
更新hash的内容为指定的data
。当使用流数据时可能会多次调用该方法。
hash.digest(encoding='binary')
Calculates the digest of all of the passed data to be hashed.The encoding
can be'hex'
, 'binary'
or 'base64'
.
计算所有传入数据的hash摘要。参数encoding
(编码方式)可以为'hex'
, 'binary'
或者'base64'
。
crypto.createHmac(algorithm, key)
Creates and returns a hmac object, a cryptographic hmac with the given algorithm and key.
创建并返回一个hmac对象,它是一个指定算法和密钥的加密hmac。
algorithm
is dependent on the available algorithms supported by OpenSSL - see createHash above.key
is the hmac key to be used.
参数algorithm
可选择OpenSSL支持的算法 - 参见上文的createHash。参数key
为hmac所使用的密钥。
hmac.update(data)
Update the hmac content with the given data
.This can be called many times with new data as it is streamed.
更新hmac的内容为指定的data
。当使用流数据时可能会多次调用该方法。
hmac.digest(encoding='binary')
Calculates the digest of all of the passed data to the hmac.The encoding
can be'hex'
, 'binary'
or 'base64'
.
计算所有传入数据的hmac摘要。参数encoding
(编码方式)可以为'hex'
, 'binary'
或者'base64'
。
crypto.createCipher(algorithm, key)
Creates and returns a cipher object, with the given algorithm and key.
使用指定的算法和密钥创建并返回一个cipher对象。
algorithm
is dependent on OpenSSL, examples are 'aes192'
, etc.On recent releases,openssl list-cipher-algorithms
will display the available cipher algorithms.
参数algorithm
可选择OpenSSL支持的算法,例如'aes192'
等。在最近的发行版中,openssl list-cipher-algorithms
会显示可用的加密的算法。
cipher.update(data, input_encoding='binary', output_encoding='binary')
Updates the cipher with data
, the encoding of which is given in input_encoding
and can be 'utf8'
, 'ascii'
or 'binary'
. The output_encoding
specifiesthe output format of the enciphered data, and can be'binary'
, 'base64'
or 'hex'
.
使用参数data
更新要加密的内容,其编码方式由参数input_encoding
指定,可以为 'utf8'
, 'ascii'
或者'binary'
。参数output_encoding
指定了已加密内容的输出编码方式,可以为'binary'
, 'base64'
或'hex'
。
Returns the enciphered contents, and can be called many times with new data as it is streamed.
返回已加密的内容,当使用流数据时可能会多次调用该方法。
cipher.final(output_encoding='binary')
Returns any remaining enciphered contents, with output_encoding
being one of:'binary'
, 'ascii'
or 'utf8'
.
返回所有剩余的加密内容,output_encoding
输出编码为'binary'
, 'ascii'
或'utf8'
其中之一。
crypto.createDecipher(algorithm, key)
Creates and returns a decipher object, with the given algorithm and key.This is the mirror of the cipher object above.
使用给定的算法和密钥创建并返回一个解密对象。该对象为上述加密对象的反向运算。
decipher.update(data, input_encoding='binary', output_encoding='binary')
Updates the decipher with data
, which is encoded in 'binary'
,'base64'
or 'hex'
.The output_decoding
specifies in what format to return the deciphered plaintext:'binary'
, 'ascii'
or 'utf8'
.
使用参数data
更新要解密的内容,其编码方式为'binary'
,'base64'
或'hex'
。参数output_encoding
指定了已解密的明文内容的输出编码方式,可以为'binary'
,'ascii'
或'utf8'
。
decipher.final(output_encoding='binary')
Returns any remaining plaintext which is deciphered,with output_encoding' being one of:
'binary',
'ascii' or
'utf8'`.
返回全部剩余的已解密的明文,其output_encoding' 为
'binary',
'ascii'或
'utf8'`其中之一。
crypto.createSign(algorithm)
Creates and returns a signing object, with the given algorithm.On recent OpenSSL releases,openssl list-public-key-algorithms
will displaythe available signing algorithms. Examples are'RSA-SHA256'
.
使用给定的算法创建并返回一个签名器对象。在现有的OpenSSL发行版中,openssl list-public-key-algorithms
会显示可用的签名算法,例如:'RSA-SHA256'
。
signer.update(data)
Updates the signer object with data.This can be called many times with new data as it is streamed.
使用data参数更新签名器对象。当使用流数据时可能会多次调用该方法。
signer.sign(private_key, output_format='binary')
Calculates the signature on all the updated data passed through the signer.private_key
is a string containing the PEM encoded private key for signing.
对所有传入签名器的数据计算其签名。private_key
为字符串,它包含了PEM编码的用于签名的私钥。
Returns the signature in output_format
which can be 'binary'
,'hex'
or 'base64'
.
返回签名,其output_format
输出可以为'binary'
, 'hex'
或者'base64'
。
crypto.createVerify(algorithm)
Creates and returns a verification object, with the given algorithm.This is the mirror of the signing object above.
使用给定算法创建并返回一个验证器对象。它是上述签名器对象的反向运算。
verifier.update(data)
Updates the verifier object with data.This can be called many times with new data as it is streamed.
使用data参数更新验证器对象。当使用流数据时可能会多次调用该方法。
verifier.verify(cert, signature, signature_format='binary')
Verifies the signed data by using the cert
which is a string containingthe PEM encoded public key, andsignature
, which is the previously calculatessignature for the data, in thesignature_format
which can be 'binary'
, 'hex'
or'base64'
.
使用参数cert
和signature
验证已签名的数据,cert
为经过PEM编码的公钥字符串,signature
为之前已计算的数据的签名,signature_format
可以为'binary'
,'hex'
或者'base64'
。
Returns true or false depending on the validity of the signature for the data and public key.
根据对数据和公钥进行签名有效性验证的结果,返回true或者false。## TLS (SSL) TLS (SSL)模块
Use require('tls')
to access this module.
使用require('tls')
访问此模块。
The tls
module uses OpenSSL to provide Transport Layer Security and/orSecure Socket Layer: encrypted stream communication.
tls
模块使用OpenSSL提供Transport Layer Security(传输层安全协议)和 / 或Secure Socket Layer(安全套接层协议):加密的通信流。
TLS/SSL is a public/private key infrastructure. Each client and eachserver must have a private key. A private key is created like this
TLS/SSL基于公钥/私钥的非对称加密体系,每一个客户端与服务器都需要拥有一个私有密钥。私有密钥可用如下方式生成:
openssl genrsa -out ryans-key.pem 1024
All severs and some clients need to have a certificate. Certificates are publickeys signed by a Certificate Authority or self-signed. The first step togetting a certificate is to create a "Certificate Signing Request" (CSR)file. This is done with:
所有服务器和一部分客户端需要拥有一份数字证书。数字证书是由某个CA(数字证书认证机构)使用其公钥签名授予的,或者也可以用户自签名。要获得一份数字证书,首先需要生成一个CSR(证书签名请求)文件。方法如下:
openssl req -new -key ryans-key.pem -out ryans-csr.pem
To create a self-signed certificate with the CSR, do this:
要使用CSR文件生成一个自签名的数字证书,方法如下:
openssl x509 -req -in ryans-csr.pem -signkey ryans-key.pem -out ryans-cert.pem
Alternatively you can send the CSR to a Certificate Authority for signing.
你也可以将CSR文件发给一家CA以获得签名。
(TODO: docs on creating a CA, for now interested users should just look attest/fixtures/keys/Makefile
in the Node source code)
(关于如何创建CA的文档有待补充。感兴趣的用户可以直接浏览Node源代码中的test/fixtures/keys/Makefile
文件)
s = tls.connect(port, [host], [options], callback)
Creates a new client connection to the given port
and host
. (Ifhost
defaults to localhost
.) options
should be an object which specifies
建立一个到指定端口port
和主机host
的新的客户端连接。(host
参数的默认值为localhost
。)options
是一个包含以下内容的对象:
-
key
: A string orBuffer
containing the private key of the server inPEM format. (Required)key
:包含服务器私钥的字符串或Buffer
对象。密钥的格式为PEM。(必选) -
cert
: A string orBuffer
containing the certificate key of the server inPEM format.cert
:包含服务器数字证书密钥的字符串或Buffer
对象。密钥的格式为PEM。 -
ca
: An array of strings orBuffer
s of trusted certificates. If this isomitted several well known "root" CAs will be used, like VeriSign.These are used to authorize connections.ca
:包含可信任数字证书字符串或Buffer
对象的数组。如果忽略此属性,则会使用几个常见的"根"CA的数字证书,如VeriSign。这些数字证书将被用来对连接进行验证。
tls.connect()
returns a cleartext CryptoStream
object.
tls.connect()
返回一个明文的CryptoStream
对象。
After the TLS/SSL handshake the callback
is called. The callback
will becalled no matter if the server's certificate was authorized or not. It is upto the user to tests.authorized
to see if the server certificate wassigned by one of the specified CAs. Ifs.authorized === false
then the errorcan be found in s.authorizationError
.
TLS/SSL连接握手之后callback
回调函数会被调用。无论服务器的数字证书是否通过验证,callback
函数都会被调用。用户应该检查s.authorized
以确定服务器数字证书是否通过了验证(被某个可信任的CA签名)。当s.authorized === false
时可以从s.authorizationError
中获得具体的错误。
tls.Server
This class is a subclass of net.Server
and has the same methods on it.Instead of accepting just raw TCP connections, this accepts encryptedconnections using TLS or SSL.
这是net.Server
的子类,拥有和net.Server
完全一样的方法。区别在于这个类使用TLS或SSL建立加密的连接,而非仅仅接受原始的TCP连接。
Here is a simple example echo server:
下面是一个简单的回声服务器的例子:
var tls = require('tls');
var fs = require('fs');
var options = {
key: fs.readFileSync('server-key.pem'),
cert: fs.readFileSync('server-cert.pem')
};
tls.createServer(options, function (s) {
s.write("welcome!\n");
s.pipe(s);
}).listen(8000);
You can test this server by connecting to it with openssl s_client
:
你可以使用openssl s_client
连接到这个服务器进行测试:
openssl s_client -connect 127.0.0.1:8000
tls.createServer(options, secureConnectionListener)
This is a constructor for the tls.Server
class. The options objecthas these possibilities:
这是tls.Server
类的构造函数。参数options对象可以包含下列内容:
-
key
: A string orBuffer
containing the private key of the server inPEM format. (Required)key
:包含服务器私钥的字符串或Buffer
对象。密钥的格式为PEM。(必选) -
cert
: A string orBuffer
containing the certificate key of the server inPEM format. (Required)cert
:包含服务器数字证书密钥的字符串或Buffer
对象。密钥的格式为PEM。(必选) -
ca
: An array of strings orBuffer
s of trusted certificates. If this isomitted several well known "root" CAs will be used, like VeriSign.These are used to authorize connections.ca
:包含可信任数字证书字符串或Buffer
对象的数组。如果忽略此属性,则会使用几个常见的"根"CA的数字证书,如VeriSign。这些证书将被用来对连接进行验证。 -
requestCert
: Iftrue
the server will request a certificate fromclients that connect and attempt to verify that certificate. Default:false
.requestCert
:如果设为true
则服务器会向建立连接的客户端要求一个数字证书,并且试图去验证这份数字证书。默认为false
。 -
rejectUnauthorized
: Iftrue
the server will reject any connectionwhich is not authorized with the list of supplied CAs. This option onlyhas an effect ifrequestCert
istrue
. Default:false
.rejectUnauthorized
:如果设为true
则服务器将拒绝任何没有通过CA验证的连接。此选项仅在requestCert
设为true
时有效。默认为false
。
Event: 'secureConnection' 事件:'secureConnection'
function (cleartextStream) {}
This event is emitted after a new connection has been successfullyhandshaked. The argument is a duplex instance ofstream.Stream
. It has allthe common stream methods and events.
当一个新的连接成功完成握手过程后此事件被触发。参数是一个可读可写的stream.Stream
实例对象,此对象具有Stream(流)对象所有公共的方法和事件。
cleartextStream.authorized
is a boolean value which indicates if theclient has verified by one of the supplied certificate authorities for theserver. IfcleartextStream.authorized
is false, thencleartextStream.authorizationError
is set to describe how authorizationfailed. Implied but worth mentioning: depending on the settings of the TLSserver, you unauthorized connections may be accepted.
cleartextStream.authorized
是一个布尔值,用以表明客户端是否通过了服务器所指定的可信任CA的验证。如果cleartextStream.authorized
值为false,则可以从cleartextStream.authorizationError
中获得验证失败的原因。这意味着:未经验证的连接是有可能被接受的,这依赖于TLS服务器的具体设置。
server.listen(port, [host], [callback])
Begin accepting connections on the specified port
and host
. If thehost
is omitted, the server will accept connections directed to anyIPv4 address (INADDR_ANY
).
开始在指定的端口port
和主机名host
上接受连接。如果没有设置host
参数,服务器将接受到达本机所有IPv4地址(INADDR_ANY
)的连接。
This function is asynchronous. The last parameter callback
will be calledwhen the server has been bound.
此函数是异步的。最后一个参数callback
所指定的回调函数会在服务器绑定完成后被调用。
See net.Server
for more information.
更多信息参见net.Server
。
server.close()
Stops the server from accepting new connections. This function isasynchronous, the server is finally closed when the server emits a'close'
event.
关闭服务器,停止接受新的连接请求。此函数是异步的,当服务器触发一个'close'
事件时才真正被关闭。
server.maxConnections
Set this property to reject connections when the server's connection count gets high.
服务器最大连接数量。服务器会拒绝超过此数量限制的连接,以防止同时建立的连接数过多。
server.connections
The number of concurrent connections on the server.
服务器并发连接数量。
File System 文件系统模块
File I/O is provided by simple wrappers around standard POSIX functions. Touse this module dorequire('fs')
. All the methods have asynchronous andsynchronous forms.
文件的I/O是由标准POSIX函数封装而成。需要使用require('fs')
访问这个模块。所有的方法都提供了异步和同步两种方式。
The asynchronous form always take a completion callback as its last argument.The arguments passed to the completion callback depend on the method, but thefirst argument is always reserved for an exception. If the operation wascompleted successfully, then the first argument will be null
or undefined
.
异步形式下,方法的最后一个参数需要传入一个执行完成时的回调函数。传给回调函数的参数取决于具体的异步方法,但第一个参数总是保留给异常对象。如果操作成功,那么该异常对象就变为null
或者undefined
。
Here is an example of the asynchronous version:
这里是一个异步调用的例子:
var fs = require('fs');
fs.unlink('/tmp/hello', function (err) {
if (err) throw err;
console.log('successfully deleted /tmp/hello');
});
Here is the synchronous version:
这里是进行相同操作的同步调用的例子:
var fs = require('fs');
fs.unlinkSync('/tmp/hello')
console.log('successfully deleted /tmp/hello');
With the asynchronous methods there is no guaranteed ordering. So thefollowing is prone to error:
由于异步方法调用无法保证执行的顺序,所以下面的代码容易导致出现错误。
fs.rename('/tmp/hello', '/tmp/world', function (err) {
if (err) throw err;
console.log('renamed complete');
});
fs.stat('/tmp/world', function (err, stats) {
if (err) throw err;
console.log('stats: ' + JSON.stringify(stats));
});
It could be that fs.stat
is executed before fs.rename
.The correct way to do this is to chain the callbacks.
这样做有可能导致fs.stat
在fs.rename
之前执行,正确的做法是链式调用回调函数。
fs.rename('/tmp/hello', '/tmp/world', function (err) {
if (err) throw err;
fs.stat('/tmp/world', function (err, stats) {
if (err) throw err;
console.log('stats: ' + JSON.stringify(stats));
});
});
In busy processes, the programmer is strongly encouraged to use theasynchronous versions of these calls. The synchronous versions will blockthe entire process until they complete--halting all connections.
当需要频繁操作时,强烈建议使用异步方法。同步方式在其完成之前将会阻塞当前的整个进程,即搁置所有连接。
fs.rename(path1, path2, [callback])
Asynchronous rename(2). No arguments other than a possible exception are givento the completion callback.
异步调用rename(2),重命名某个文件,除非回调函数执行过程出现了异常,否则不会传递任何参数。
fs.renameSync(path1, path2)
Synchronous rename(2).
同步调用重命名rename(2),重命名某个文件。
fs.truncate(fd, len, [callback])
Asynchronous ftruncate(2). No arguments other than a possible exception aregiven to the completion callback.
异步调用ftruncate(2),截断某个文件,除非回调函数执行过程出现了异常,否则不会传递任何参数。
fs.truncateSync(fd, len)
Synchronous ftruncate(2).
同步调用重命名ftruncate(2),截断某个文件s。
fs.chmod(path, mode, [callback])
Asynchronous chmod(2). No arguments other than a possible exception are givento the completion callback.
异步调用chmod(2),修改文件权限,除非回调函数执行过程出现了异常,否则不会传递任何参数。
fs.chmodSync(path, mode)
Synchronous chmod(2).
同步调用chmod(2),修改文件权限。
fs.stat(path, [callback])
Asynchronous stat(2). The callback gets two arguments (err, stats)
wherestats
is afs.Stats
object. It looks like this:
异步调用stat(2),读取文件元信息,回调函数将返回两个参数(err, stats)
,其中stats
是fs.Stats
的一个对象,如下所示:
{ dev: 2049,
ino: 305352,
mode: 16877,
nlink: 12,
uid: 1000,
gid: 1000,
rdev: 0,
size: 4096,
blksize: 4096,
blocks: 8,
atime: '2009-06-29T11:11:55Z',
mtime: '2009-06-29T11:11:40Z',
ctime: '2009-06-29T11:11:40Z' }
See the fs.Stats
section below for more information.
有关详细信息,请参阅下面的fs.Stats
部分
fs.lstat(path, [callback])
Asynchronous lstat(2). The callback gets two arguments (err, stats)
wherestats
is afs.Stats
object. lstat() is identical to stat(), except that ifpath is a symbolic link, then the link itself is stat-ed, not the file that itrefers to.
异步形式调用lstat(2),回调函数返回两个参数(err, stats)
,其中stats
是fs.Stats
的一个对象,lstat()和stat()类似,区别在于当path是一个符号链接时,它指向该链接的属性,而不是所指向文件的属性.
fs.fstat(fd, [callback])
Asynchronous fstat(2). The callback gets two arguments (err, stats)
wherestats
is afs.Stats
object.
异步形式调用fstat(2),回调函数返回两个参数(err, stats)
,其中stats
是fs.Stats
的一个对象。
fs.statSync(path)
Synchronous stat(2). Returns an instance of fs.Stats
.
同步形式调用stat(2),返回fs.Stats
的一个实例。
fs.lstatSync(path)
Synchronous lstat(2). Returns an instance of fs.Stats
.
同步形式调用lstat(2),返回fs.Stats
的一个实例。
fs.fstatSync(fd)
Synchronous fstat(2). Returns an instance of fs.Stats
.
同步形式调用fstatSync(2),返回fs.Stats
的一个实例。
fs.link(srcpath, dstpath, [callback])
Asynchronous link(2). No arguments other than a possible exception are given tothe completion callback.
异步调用link(2),创建符号连接,除非回调函数执行过程出现了异常,否则不会传递任何参数。
fs.linkSync(srcpath, dstpath)
Synchronous link(2).
同步调用link(2)。
fs.symlink(linkdata, path, [callback])
Asynchronous symlink(2). No arguments other than a possible exception are givento the completion callback.
异步调用symlink(2),除非回调函数执行过程出现了异常,否则不会传递任何参数。
fs.symlinkSync(linkdata, path)
Synchronous symlink(2).
同步调用symlink(2)。
fs.readlink(path, [callback])
Asynchronous readlink(2). The callback gets two arguments (err,resolvedPath)
.
异步调用readlink,回调函数返回两个参数(err,resolvedPath)
,resolvedPath
为解析后的文件路径。
fs.readlinkSync(path)
Synchronous readlink(2). Returns the resolved path.
同步调用readlink(2),返回解析后的文件路径。
fs.realpath(path, [callback])
Asynchronous realpath(2). The callback gets two arguments (err,resolvedPath)
.
异步调用realpath(2),回调函数返回两个参数(err,resolvedPath)
,resolvedPath为解析后的文件路径。
fs.realpathSync(path)
Synchronous realpath(2). Returns the resolved path.
同步调用realpath(2),返回解析后的文件路径。
fs.unlink(path, [callback])
Asynchronous unlink(2). No arguments other than a possible exception are givento the completion callback.
异步调用unlink(2),删除链接或者文件,除非回调函数执行过程出现了异常,否则不会传递任何参数。
fs.unlinkSync(path)
Synchronous unlink(2).
同步调用unlink(2)。
fs.rmdir(path, [callback])
Asynchronous rmdir(2). No arguments other than a possible exception are givento the completion callback.
异步调用rmdir(2),除非回调函数执行过程出现了异常,否则不会传递任何参数。
fs.rmdirSync(path)
Synchronous rmdir(2).
同步调用rmdir(2)。
fs.mkdir(path, mode, [callback])
Asynchronous mkdir(2). No arguments other than a possible exception are givento the completion callback.
异步调用mkdir(2),除非回调函数执行过程出现了异常,否则不会传递任何参数。
fs.mkdirSync(path, mode)
Synchronous mkdir(2).
同步调用mkdir(2)。
fs.readdir(path, [callback])
Asynchronous readdir(3). Reads the contents of a directory.The callback gets two arguments(err, files)
where files
is an array ofthe names of the files in the directory excluding'.'
and '..'
.
异步调用readdir(3),读取目录中的内容。回调函数接受两个参数(err, files)
,其中files
参数是保存了目录中所有文件名的数组('.'
和'..'
除外)。
fs.readdirSync(path)
Synchronous readdir(3). Returns an array of filenames excluding '.'
and'..'
.
同步调用readdir(3)。返回目录中文件名数组('.'
与'..'
除外)。
fs.close(fd, [callback])
Asynchronous close(2). No arguments other than a possible exception are givento the completion callback.
异步同步调用close(2),关闭文件,除非回调函数执行过程出现了异常,否则不会传递任何参数。
fs.closeSync(fd)
Synchronous close(2).
同步调用close(2)。
fs.open(path, flags, mode=0666, [callback])
Asynchronous file open. See open(2). Flags can be 'r', 'r+', 'w', 'w+', 'a',or 'a+'. The callback gets two arguments(err, fd)
.
异步开启文件,详阅open(2)。标签可为'r', 'r+', 'w', 'w+', 'a', 或 'a+'。回调函数接受两个参数(err, fd)
。
fs.openSync(path, flags, mode=0666)
Synchronous open(2).
同步调用open(2)。
fs.utimes(path, atime, mtime, callback)
fs.utimesSync(path, atime, mtime)
Change file timestamps.
更改文件时间戳。
fs.futimes(path, atime, mtime, callback)
fs.futimesSync(path, atime, mtime)
Change file timestamps with the difference that if filename refers to asymbolic link, then the link is not dereferenced.
另一种更改文件时间戳的方式。区别在于如果文件名指向一个符号链接,则改变此符号链接的时间戳,而不改变所引用文件的时间戳。
fs.write(fd, buffer, offset, length, position, [callback])
Write buffer
to the file specified by fd
.
将buffer
缓冲器内容写入fd
文件描述符。
offset
and length
determine the part of the buffer to be written.
offset
和length
决定了将缓冲器中的哪部分写入文件。
position
refers to the offset from the beginning of the file where this datashould be written. Ifposition
is null
, the data will be written at thecurrent position.See pwrite(2).
position
指明将数据写入文件从头部算起的偏移位置,若position
为null
,数据将从当前位置开始写入,详阅pwrite(2)。
The callback will be given two arguments (err, written)
where written
specifies how many bytes were written.
回调函数接受两个参数(err, written)
,其中written
标识有多少字节的数据已经写入。
fs.writeSync(fd, buffer, offset, length, position)
Synchronous version of buffer-based fs.write()
. Returns the number of byteswritten.
基于缓冲器的fs.write()
的同步版本,返回写入数据的字节数。
fs.writeSync(fd, str, position, encoding='utf8')
Synchronous version of string-based fs.write()
. Returns the number of byteswritten.
基于字符串的fs.write()
的同步版本,返回写入数据的字节数。
fs.read(fd, buffer, offset, length, position, [callback])
Read data from the file specified by fd
.
从fd
文件描述符中读取数据。
buffer
is the buffer that the data will be written to.
buffer
为写入数据的缓冲器。
offset
is offset within the buffer where writing will start.
offset
为写入到缓冲器的偏移地址。
length
is an integer specifying the number of bytes to read.
length
指明了欲读取的数据字节数。
position
is an integer specifying where to begin reading from in the file.Ifposition
is null
, data will be read from the current file position.
position
为一个整形变量,标识从哪个位置开始读取文件,如果position
参数为null
,数据将从文件当前位置开始读取。
The callback is given the two arguments, (err, bytesRead)
.
回调函数接受两个参数,(err, bytesRead)
。
fs.readSync(fd, buffer, offset, length, position)
Synchronous version of buffer-based fs.read
. Returns the number ofbytesRead
.
基于缓冲器的fs.read
的同步版本,返回读取到的bytesRead
字节数。
fs.readSync(fd, length, position, encoding)
Synchronous version of string-based fs.read
. Returns the number ofbytesRead
.
基于字符串的fs.read
的同步版本,返回已经读入的数据的字节数。
fs.readFile(filename, [encoding], [callback])
Asynchronously reads the entire contents of a file. Example:
异步读取一个文件的所有内容,例子如下:
fs.readFile('/etc/passwd', function (err, data) {
if (err) throw err;
console.log(data);
});
The callback is passed two arguments (err, data)
, where data
is thecontents of the file.
回调函数将传入两个参数(err, data)
,其中data
为文件内容。
If no encoding is specified, then the raw buffer is returned.
如果没有设置编码,那么将返回原始内容格式的缓冲器。
fs.readFileSync(filename, [encoding])
Synchronous version of fs.readFile
. Returns the contents of the filename
.
同步调用fs.readFile
的版本,返回指定文件filename
的文件内容。
If encoding
is specified then this function returns a string. Otherwise itreturns a buffer.
如果设置了encoding
参数,将返回一个字符串。否则返回一个缓冲器。
fs.writeFile(filename, data, encoding='utf8', [callback])
Asynchronously writes data to a file. data
can be a string or a buffer.
异步写入数据到某个文件中,data
可以是字符串或者缓冲器。
Example:
例子:
fs.writeFile('message.txt', 'Hello Node', function (err) {
if (err) throw err;
console.log('It\'s saved!');
});
fs.writeFileSync(filename, data, encoding='utf8')
The synchronous version of fs.writeFile
.
同步调用fs.writeFile
的方式。
fs.watchFile(filename, [options], listener)
Watch for changes on filename
. The callback listener
will be called eachtime the file is accessed.
监听指定文件filename
的变化,回调函数listener
将在每次该文件被访问时被调用。
The second argument is optional. The options
if provided should be an objectcontaining two members a boolean,persistent
, and interval
, a pollingvalue in milliseconds. The default is{ persistent: true, interval: 0 }
.
第二个参数是可选项,如果指定了options
参数,它应该是一个包含如下内容的对象:名为persistent
的布尔值,和名为interval
单位为毫秒的轮询时间间隔,默认值为{ persistent: true, interval: 0 }
。
The listener
gets two arguments the current stat object and the previousstat object:
listener
监听器将获得两个参数,分别标识当前的状态对象和改变前的状态对象。
fs.watchFile(f, function (curr, prev) {
console.log('the current mtime is: ' + curr.mtime);
console.log('the previous mtime was: ' + prev.mtime);
});
These stat objects are instances of fs.Stat
.
这些状态对象为fs.Stat
的实例。
If you want to be notified when the file was modified, not just accessedyou need to comparecurr.mtime
and `prev.mtime.
如果你想在文件被修改而不是被访问时得到通知,你还需要比较curr.mtime
和prev.mtime
的值。
fs.unwatchFile(filename)
Stop watching for changes on filename
.
停止监听文件filename
的变化。
fs.Stats
Objects returned from fs.stat()
and fs.lstat()
are of this type.
fs.stat()
和 fs.lstat()
方法返回的对象为此类型。
stats.isFile()
stats.isDirectory()
stats.isBlockDevice()
stats.isCharacterDevice()
stats.isSymbolicLink()
(only valid withfs.lstat()
)stats.isSymbolicLink()
(仅对fs.lstat()
有效)stats.isFIFO()
stats.isSocket()
fs.ReadStream
ReadStream
is a Readable Stream
.
ReadStream
是一个Readable Stream
可读流。
fs.createReadStream(path, [options])
Returns a new ReadStream object (See Readable Stream
).
返回一个新的可读流对象(参见Readable Stream
)。
options
is an object with the following defaults:
options
是包含如下默认值的对象:
{ flags: 'r',
encoding: null,
fd: null,
mode: 0666,
bufferSize: 64 * 1024
}
options
can include start
and end
values to read a range of bytes fromthe file instead of the entire file. Bothstart
and end
are inclusive andstart at 0. When used, both the limits must be specified always.
如果不想读取文件的全部内容,可以在options
参数中设置start
和end
属性值以读取文件中指定范围的内容。start
和end
包含在范围中(闭集合),取值从0开始。这两个参数需要同时设置。
An example to read the last 10 bytes of a file which is 100 bytes long:
一个例子演示了从一个长度为100字节的文件中读取最后10个字节:
fs.createReadStream('sample.txt', {start: 90, end: 99});
fs.WriteStream
WriteStream
is a Writable Stream
.
WriteStream
为可写流。
Event: 'open' 事件:'open'
function (fd) { }
fd
is the file descriptor used by the WriteStream.
fd
是可写流所使用的文件描述符。
fs.createWriteStream(path, [options])
Returns a new WriteStream object (See Writable Stream
).
返回一个新的可写流对象(参见Writable Stream
)。
options
is an object with the following defaults:
options
参数是包含如下默认值的对象:
{ flags: 'w',
encoding: null,
mode: 0666 }
Path 路径模块
This module contains utilities for dealing with file paths. Userequire('path')
to use it. It provides the following methods:
该模块包括了一些处理文件路径的功能,可以通过require('path')
方法来使用它。该模块提供了如下的方法:
path.normalize(p)
Normalize a string path, taking care of '..'
and '.'
parts.
该方法用于标准化一个字符型的路径,请注意'..'
与 '.'
的使用。
When multiple slashes are found, they're replaces by a single one;when the path contains a trailing slash, it is preserved.On windows backslashes are used.
当发现有多个斜杠(/)时,系统会将他们替换为一个斜杠;如果路径末尾中包含有一个斜杠,那么系统会保留这个斜杠。在Windows中,上述路径中的斜杠(/)要换成反斜杠(\)。
Example:
示例:
path.normalize('/foo/bar//baz/asdf/quux/..')
// returns
'/foo/bar/baz/asdf'
path.join([path1], [path2], [...])
Join all arguments together and normalize the resulting path.
该方法用于合并方法中的各参数并得到一个标准化合并的路径字符串。
Example:
示例:
node> require('path').join(
... '/foo', 'bar', 'baz/asdf', 'quux', '..')
'/foo/bar/baz/asdf'
path.resolve([from ...], to)
Resolves to
to an absolute path.
将to
参数解析为绝对路径。
If to
isn't already absolute from
arguments are prepended in right to leftorder, until an absolute path is found. If after using allfrom
paths stillno absolute path is found, the current working directory is used as well. Theresulting path is normalized, and trailing slashes are removed unless the path gets resolved to the root directory.
如果参数 to
当前不是绝对的,系统会将from
参数按从右到左的顺序依次前缀到to
上,直到在from
中找到一个绝对路径时停止。如果遍历所有from
中的路径后,系统依然没有找到一个绝对路径,那么当前工作目录也会作为参数使用。最终得到的路径是标准化的字符串,并且标准化时系统会自动删除路径末尾的斜杠,但是如果获取的路径是解析到根目录的,那么系统将保留路径末尾的斜杠。
Another way to think of it is as a sequence of cd
commands in a shell.
你也可以将这个方法理解为Shell中的一组cd
命令。
path.resolve('foo/bar', '/tmp/file/', '..', 'a/../subfile')
Is similar to:
就类似于:
cd foo/bar
cd /tmp/file/
cd ..
cd a/../subfile
pwd
The difference is that the different paths don't need to exist and may also befiles.
该方法与cd
命令的区别在于该方法中不同的路径不一定存在,而且这些路径也可能是文件。
Examples:
示例:
path.resolve('/foo/bar', './baz')
// returns
'/foo/bar/baz'
path.resolve('/foo/bar', '/tmp/file/')
// returns
'/tmp/file'
path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif')
// if currently in /home/myself/node, it returns
'/home/myself/node/wwwroot/static_files/gif/image.gif'
path.dirname(p)
Return the directory name of a path. Similar to the Unix dirname
command.
该方法返回一个路径的目录名,类似于Unix中的dirname
命令。
Example:
示例:
path.dirname('/foo/bar/baz/asdf/quux')
// returns
'/foo/bar/baz/asdf'
path.basename(p, [ext])
Return the last portion of a path. Similar to the Unix basename
command.
该方法返回一个路径中最低一级目录名,类似于Unix中的 basename
命令。
Example:
示例:
path.basename('/foo/bar/baz/asdf/quux.html')
// returns
'quux.html'
path.basename('/foo/bar/baz/asdf/quux.html', '.html')
// returns
'quux'
path.extname(p)
Return the extension of the path. Everything after the last '.' in the last portionof the path. If there is no '.' in the last portion of the path or the only '.' isthe first character, then it returns an empty string.
该方法返回路径中的文件扩展名,即路径最低一级的目录中'.'字符后的任何字符串。如果路径最低一级的目录中'没有'.' 或者只有'.',那么该方法返回一个空字符串。
Examples:
示例:
path.extname('index.html')
// returns
'.html'
path.extname('index')
// returns
''
path.exists(p, [callback])
Test whether or not the given path exists. Then, call the callback
argumentwith either true or false. Example:
该方法用于测试参数p
中的路径是否存在。然后以true或者false作为参数调用callback
回调函数。示例:
path.exists('/etc/passwd', function (exists) {
util.debug(exists ? "it's there" : "no passwd!");
});
path.existsSync(p)
Synchronous version of path.exists
.
path.exists
的同步版本。## net 网络模块
The net
module provides you with an asynchronous network wrapper. It containsmethods for creating both servers and clients (called streams). You can includethis module withrequire("net");
net
模块为你提供了一种异步网络包装器,它包含创建服务器和客户端(称为streams)所需的方法,您可以通过调用require("net")
来使用此模块。
net.createServer([options], [connectionListener])
Creates a new TCP server. The connectionListener
argument isautomatically set as a listener for the'connection'
event.
创建一个新的TCP服务器,参数connectionListener
被自动设置为connection事件的监听器。
options
is an object with the following defaults:
options
参数为一个对象,默认值如下: { allowHalfOpen: false }
If allowHalfOpen
is true
, then the socket won't automatically send FINpacket when the other end of the socket sends a FIN packet. The socket becomesnon-readable, but still writable. You should call the end() method explicitly.See'end'
event for more information.
如果allowHalfOpen
参数为true
,则当客户端socket发送FIN包时,服务器端socket不会自动发送FIN包。此情况下服务器端socket将变为不可读状态,但仍然可写。你需要明确的调用end()方法来关闭连接。更多内容请参照'end'
事件。
net.createConnection(arguments...)
Construct a new socket object and opens a socket to the given location. Whenthe socket is established the'connect'
event will be emitted.
创建一个新的socket对象,并建立到指定地址的socket连接。当socket建立后,'connect'
事件将被触发。
The arguments for this method change the type of connection:
不同的参数决定了连接的类型:
-
net.createConnection(port, [host])
Creates a TCP connection to
port
onhost
. Ifhost
is omitted,localhost
will be assumed.创建一个到主机
host
的port
端口的TCP连接,如果略了host
参数,默认连接到localhost
。 -
net.createConnection(path)
Creates unix socket connection to
path
创建连接到
path
路径的unix socket。
net.Server
This class is used to create a TCP or UNIX server.
这个类用于创建一个TCP或UNIX服务器。
Here is an example of a echo server which listens for connectionson port 8124:
下面的例子创建了一个在8124端口监听的echo
服务器。
var net = require('net');
var server = net.createServer(function (c) {
c.write('hello\r\n');
c.pipe(c);
});
server.listen(8124, 'localhost');
Test this by using telnet
:
使用telnet
测试该服务器。
telnet localhost 8124
To listen on the socket /tmp/echo.sock
the last line would just bechanged to
如要监听socket /tmp/echo.sock
,最后一行代码需要修改成:
server.listen('/tmp/echo.sock');
Use nc
to connect to a UNIX domain socket server:
使用nc
命令连接到一个UNIX域socket服务器:
nc -U /tmp/echo.sock
net.Server
is an EventEmitter
with the following events:
net.Server
是下列事件的 EventEmitter
(事件触发器):
server.listen(port, [host], [callback])
Begin accepting connections on the specified port
and host
. If thehost
is omitted, the server will accept connections directed to anyIPv4 address (INADDR_ANY
).
开始接收特定主机host
的port
端口的连接,如果省略了host
参数,服务器将接收任何指向IPV4地址的连接。
This function is asynchronous. The last parameter callback
will be calledwhen the server has been bound.
此函数是异步的,在服务器被绑定时,最后一个参数callback
回调函数将被调用。
One issue some users run into is getting EADDRINUSE
errors. Meaninganother server is already running on the requested port. One way of handling thiswould be to wait a second and the try again. This can be done with
一些用户可能会遇到EADDRINUSE
错误,该错误消息的意思是已经有另一个服务运行在请求的端口上,一个解决方法就是等一会再试一下,就像下面的代码这样:
server.on('error', function (e) {
if (e.code == 'EADDRINUSE') {
console.log('Address in use, retrying...');
setTimeout(function () {
server.close();
server.listen(PORT, HOST);
}, 1000);
}
});
(Note: All sockets in Node are set SO_REUSEADDR already)
(注意:Node中所有的socket都已经设置成SO_REUSEADDR端口重用模式)
server.listen(path, [callback])
Start a UNIX socket server listening for connections on the given path
.
启动一个UNIX socket服务,监听指定的path
路径上的连接。
This function is asynchronous. The last parameter callback
will be calledwhen the server has been bound.
此函数是异步的,在服务器被绑定时,最后一个参数callback
回调函数将被调用。
server.listenFD(fd)
Start a server listening for connections on the given file descriptor.
启动一个服务,监听指定的文件描述符上的连接。
This file descriptor must have already had the bind(2)
and listen(2)
systemcalls invoked on it.
此文件描述符上必须已经执行了 bind(2)
和listen(2)
系统调用。
server.close()
Stops the server from accepting new connections. This function isasynchronous, the server is finally closed when the server emits a'close'
event.
关闭服务,停止接收新的连接。该函数是异步的,当服务发出'close'
事件时该服务器被最终关闭。
server.address()
Returns the bound address of the server as seen by the operating system.Useful to find which port was assigned when giving getting an OS-assigned address
返回绑定到操作系统的服务器地址。如果绑定地址是由操作系统自动分配的,可用此方法查看具体的端口号。
Example:
var server = net.createServer(function (socket) {
socket.end("goodbye\n");
});
// grab a random port.
server.listen(function() {
address = server.address();
console.log("opened server on %j", address);
});
server.maxConnections
Set this property to reject connections when the server's connection count gets high.
设置该属性的值,以便当服务器达到最大连接数时不再接受新的连接。
server.connections
The number of concurrent connections on the server.
服务器的并发连接数。
Event: 'connection' 事件:'connection'
function (socket) {}
Emitted when a new connection is made. socket
is an instance ofnet.Socket
.
当一个新的连接建立时触发。socket
是net.Socket
的一个实例。
Event: 'close'
function () {}
Emitted when the server closes.
当服务器关闭时触发。
net.Socket
This object is an abstraction of of a TCP or UNIX socket. net.Socket
instances implement a duplex Stream interface. They can be created by theuser and used as a client (withconnect()
) or they can be created by Nodeand passed to the user through the'connection'
event of a server.
这是TCP或UNIX socket的抽象对象。net.Socket
实例实现了一个全双工的流接口。此实例可以是由用户建立用作客户端(使用connect()
方法),也可能由Node建立并通过服务器的'connection'
事件传给用户。
net.Socket
instances are EventEmitters with the following events:
net.Socket
的实例是下列事件的事件触发器:
new net.Socket([options])
Construct a new socket object.
构造一个新的socket对象。
options
is an object with the following defaults:
options
参数是一个对象,默认值如下:
{ fd: null
type: null
allowHalfOpen: false
}<