// server/route.js
const fs = require('fs')module.exports = function (request, response, filePath){
fs.stat(filePath, (err, stats) => {
if (err) {
response.statusCode = 404
response.setHeader('content-type', 'text/plain')
response.end(`${filePath} is not a file`)
return;
}
if (stats.isFile()) {
response.statusCode = 200
response.setHeader('content-type', 'text/plain')
fs.createReadStream(filePath).pipe(response)
}
else if (stats.isDirectory()) {
fs.readdir(filePath, (err, files) => {
response.statusCode = 200
response.setHeader('content-type', 'text/plain')
response.end(files.join(','))
})
}
})
}
其中
fs.createReadStream() 读取文件流,
pipe() 是分段读取文件到内存,优化高并发的情况。修改之前的 http server ,引入上面新建的 route.js 作为响应函数:
// server/http.js
const http = require('http')
const path = require('path')const config = require('./config')
const route = require('./route')
const server = http.createServer((request, response) => {
let filePath = path.join(config.root, request.url)
route(request, response, filePath)
})
server.listen(config.port, config.host, () => {
const addr = `http://${config.host}:${config.port}`
console.info(`server started at ${addr}`)
})
再次执行
$ node server/http.js 如果是文件夹则显示目录:
如果是文件则直接输出:

成熟的静态资源服务器 anywhere,深入理解 nodejs 作者写的。
三、util.promisify 优化 fs 异步
我们注意到
fs.stat() 和
fs.readdir() 都有 callback 回调。我们结合 Node 的 util.promisify() 来链式操作,代替地狱回调。util.promisify 只是返回一个 Promise 实例来方便异步操作,并且可以和 async/await 配合使用,修改 route.js 中 fs 操作相关的代码:
// server/route.js
const fs = require('fs')
const util = require('util')const stat = util.promisify(fs.stat)
const readdir = util.promisify(fs.readdir)
module.exports = async function (request, response, filePath) {
try {
const stats = await stat(filePath)
if (stats.isFile()) {
response.statusCode = 200
response.setHeader('content-type', 'text/plain')
fs.createReadStream(filePath).pipe(response)









