如何列出与node.js IN ORDER目录的内容?

我是一个相当有经验的程序员,最近刚刚发现了node.js。 我喜欢JavaScript,因为这是我开始的地方(Web开发),所以能够编写服务器端代码是非常棒的。

目前,我正在做一个简单的练习,一个WebSocket / HTTP服务器,当我遇到轻微的烦恼时,我开始添加一个目录列表function:当我列出目录和文件在一个特定的目录中,他们不在订购。 我希望他们首先列出目录,第二个比字母顺序文件(如'ls'命令)。 我有一个感觉,因为它的asynchronous,但我不完全积极。 任何帮助,将不胜感激。

顺便说一句,这是我的代码:

var sys = require("sys"); var ws = require('websocket-server'); var fs = require("fs"); var path = require("path"); var url = require("url"); function log(data){ sys.log("\033[0;32m"+data+"\033[0m"); } var server = ws.createServer(); server.listen(3400); log("Listening on 3400 for HTTP and WS"); server.addListener("request", function(request, response){ log("HTTP: Connected: " + request.connection.remoteAddress); var uri = url.parse(request.url).pathname; var filename = path.join("/home/brandon", uri); log("HTTP: " + request.connection.remoteAddress + " Requested: " + filename); path.exists(filename, function(exists) { if(!exists) { response.writeHead(404, {"Content-Type": "text/plain"}); response.write("404 Not Found\n"); log("HTTP: " + filename + " Does Not Exist. 404 returned to " + request.connection.remoteAddress); response.end(); log("HTTP: Disconnected: " + request.connection.remoteAddress); return; } fs.readFile(filename, "binary", function(err, file) { if(err) { if(err.errno === 21){ fs.readdir(filename, function(err1, files){ if(err1){ response.writeHead(500, {"Content-Type": "text/plain"}); response.write("Error when reading directory: " + err1 + "\n"); log("HTTP: " + filename + " Could Not Be Read. 500 returned to " + request.connection.remoteAddress); response.end(); log("HTTP: Disconnected: " + request.connection.remoteAddress); return; } else { response.writeHead(200); response.write("<HTML><HEAD><title>Directory Listing for " + uri + "</title></HEAD><BODY><h1>Directory Listing for " + uri + "</h1>"); response.write("<ul>"); function printBr(element, index, array) { response.write("<li>" + element + "</li>"); } /*for( i in files ){ response.write("<li>" + files[i] + "</li>"); }*/ files.forEach(printBr); response.write("</ul>"); response.write("</BODY></HTML>"); log("HTTP: Directory listing for " + filename + " sent to " + request.connection.remoteAddress); response.end(); log("HTTP: Disconnected: " + request.connection.remoteAddress); return; } }); return; } response.writeHead(500, {"Content-Type": "text/plain"}); response.write("Error when reading file: " + err + "\n"); log("HTTP: " + filename + " Could Not Be Read. 500 returned to " + request.connection.remoteAddress); response.end(); log("HTTP: Disconnected: " + request.connection.remoteAddress); return; } response.writeHead(200); response.write(file, "binary"); log("HTTP: " + filename + " Read and Sent to " + request.connection.remoteAddress); response.end(); log("HTTP: Disconnected: " + request.connection.remoteAddress); }); }); }); server.addListener("connection", function(conn){ log(conn.id + ": new connection"); server.broadcast("New Connection: "+conn.id); conn.addListener("readyStateChange", function(readyState){ log("stateChanged: "+readyState); }); conn.addListener("close", function(){ var c = this; log(c.id + ": Connection Closed"); server.broadcast("Connection Closed: "+c.id); }); conn.addListener("message", function(message){ log(conn.id + ": "+JSON.stringify(message)); server.broadcast(conn.id + ": "+message); }); }); 

这里是浏览器中的输出: 在浏览器中输出

**解决了:**

感谢@萨米尔,我发现如何做到我想做的事情。 我遍历目录内容的数组,检查一个项目是一个目录或文件,将它们分成两个数组(dirs_in为dirs,'files_in'为文件),按照字母顺序对这两个数组进行sorting,最后写出来。

代码(第42-70行):

 response.writeHead(200); response.write("<HTML><HEAD><title>Directory Listing for " + uri + "</title></HEAD><BODY><h1>Directory Listing for " + uri + "</h1>"); response.write("<ul>"); function printBr(element, index, array) { response.write("<li>" + element); if( fs.statSync( path.join(filename + element) ).isDirectory() ){ response.write(" is a <b>dir</b>"); } else { response.write(" is a <b>file</b>"); } response.write("</li>"); } var dirs_in = []; var files_in = []; function sep(element, index, array) { if( fs.statSync( path.join(filename + element) ).isDirectory() ){ dirs_in.push(element); } else { files_in.push(element); } } files.forEach(sep); dirs_in.sort().forEach(printBr); files_in.sort().forEach(printBr); response.write("</ul>"); response.write("</BODY></HTML>"); log("HTTP: Directory listing for " + filename + " sent to " + request.connection.remoteAddress); response.end(); log("HTTP: Disconnected: " + request.connection.remoteAddress); 

浏览器输出: 问题解决了 PS我会删除'是一个目录'和'是一个文件'。 他们只是为了testing。

如果你想让它们按名字sort() ,你可以先调用数组的sort()

 files.sort().forEach(printBr); 

例如,如果您想先sorting目录,则需要获取更多信息。 一个天真的实现将是在sorting比较函数中查询每个文件的统计信息:

 files.sort(function(a, b) { var aIsDir = fs.statSync(dir + "/" + a).isDirectory(), bIsDir = fs.statSync(dir + "/" + b).isDirectory(); if (aIsDir && !bIsDir) { return -1; } if (!aIsDir && bIsDir) { return 1; } return a.localCompare(b); }).forEach(printBr); 

localCompare方法是sort方法默认使用的比较函数,所以我们委托给它们,如果它们都是“相等”的话。 您可以根据需要进行扩展。 我还build议您至less将isDirectory的结果存储在地图或其他东西中。 另外, statSync适用于演示目的,但不适用于生产代码。 改用stat 。 这确实会导致稍微复杂的代码,但asynchronous行为的好处是值得的。