博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

基于node.js的简单文件服务器

Posted on 2010-11-28 20:37  三块石头  阅读(7961)  评论(2)    收藏  举报

最近看了下Node.js,基于V8的服务端javascript,有点意思,就写了个简单的文件夹系统,用于列出系统的某个文件夹下的文件,并可以实现下载。不过对于比较大的文件,可能会有点问题。cygwin版本node.js及代码下载地址为猛击下载

filesystem.js
/***
* @author flyingzl
* @date 2010-11-27
* 一个基于Node.js的简单文件服务器
*/

var fs=require("fs"),
http
=require("http"),
url
=require("url"),
path
=require("path"),
mime
=require("./mime").mime,
util
=require('util');

//www根目录
var root=__dirname,
host
="127.0.0.1",
port
="8888";


if(!path.existsSync(root)){
util.error(root
+"文件夹不存在,请重新制定根文件夹!");
process.exit();
}

//显示文件夹下面的文件
function listDirectory(parentDirectory,req,res){
fs.readdir(parentDirectory,
function(error,files){
var body=formatBody(parentDirectory,files);
res.writeHead(
200,{
"Content-Type":"text/html;charset=utf-8",
"Content-Length":Buffer.byteLength(body,'utf8'),
"Server":"NodeJs("+process.version+")"
});
res.write(body,
'utf8');
res.end();
});

}

//显示文件内容
function showFile(file,req,res){
fs.readFile(filename,
'binary',function(err,file){
var contentType=mime.lookupExtension(path.extname(filename));
res.writeHead(
200,{
"Content-Type":contentType,
"Content-Length":Buffer.byteLength(file,'binary'),
"Server":"NodeJs("+process.version+")"
});
res.write(file,
"binary");
res.end();
})
}

//在Web页面上显示文件列表,格式为<ul><li></li><li></li></ul>
function formatBody(parent,files){
var res=[],
length
=files.length;
res.push(
"<!doctype>");
res.push(
"<html>");
res.push(
"<head>");
res.push(
"<meta http-equiv='Content-Type' content='text/html;charset=utf-8'></meta>")
res.push(
"<title>Node.js文件服务器</title>");
res.push(
"</head>");
res.push(
"<body width='100%'>");
res.push(
"<ul>")
files.forEach(
function(val,index){
var stat=fs.statSync(path.join(parent,val));
if(stat.isDirectory(val)){
val
=path.basename(val)+"/";
}
else{
val
=path.basename(val);
}
res.push(
"<li><a href='"+val+"'>"+val+"</a></li>");
});
res.push(
"</ul>");
res.push(
"<div style='position:relative;width:98%;bottom:5px;height:25px;background:gray'>");
res.push(
"<div style='margin:0 auto;height:100%;line-height:25px;text-align:center'>Powered By Node.js</div>");
res.push(
"</div>")
res.push(
"</body>");
return res.join("");
}

//如果文件找不到,显示404错误
function write404(req,res){
var body="文件不存在:-(";
res.writeHead(
404,{
"Content-Type":"text/html;charset=utf-8",
"Content-Length":Buffer.byteLength(body,'utf8'),
"Server":"NodeJs("+process.version+")"
});
res.write(body);
res.end();
}

//创建服务器
http.createServer(function(req,res){
//将url地址的中的%20替换为空格,不然Node.js找不到文件
var pathname=url.parse(req.url).pathname.replace(/%20/g,' '),
re
=/(%[0-9A-Fa-f]{2}){3}/g;
//能够正确显示中文,将三字节的字符转换为utf-8编码
pathname=pathname.replace(re,function(word){
var buffer=new Buffer(3),
array
=word.split('%');
array.splice(
0,1);
array.forEach(
function(val,index){
buffer[index]
=parseInt('0x'+val,16);
});
return buffer.toString('utf8');
});
if(pathname=='/'){
listDirectory(root,req,res);
}
else{
filename
=path.join(root,pathname);
path.exists(filename,
function(exists){
if(!exists){
util.error(
'找不到文件'+filename);
write404(req,res);
}
else{
fs.stat(filename,
function(err,stat){
if(stat.isFile()){
showFile(filename,req,res);
}
else if(stat.isDirectory()){
listDirectory(filename,req,res);
}
});
}
});
}


}).listen(port,host);

util.debug(
"服务器开始运行 http://"+host+":"+port)

接下来是mime.js文件,用于探测文件的类型,比如是txt还是js文件等。

mime.js
var mime = {

//查找文件后缀类型
lookupExtension : function(ext, fallback) {
return mime.TYPES[ext.toLowerCase()] || fallback || 'text/plain';
},

//文件类型
TYPES : { ".3gp" : "video/3gpp"
,
".a" : "application/octet-stream"
,
".ai" : "application/postscript"
,
".aif" : "audio/x-aiff"
,
".aiff" : "audio/x-aiff"
,
".asc" : "application/pgp-signature"
,
".asf" : "video/x-ms-asf"
,
".asm" : "text/x-asm"
,
".asx" : "video/x-ms-asf"
,
".atom" : "application/atom+xml"
,
".au" : "audio/basic"
,
".avi" : "video/x-msvideo"
,
".bat" : "application/x-msdownload"
,
".bin" : "application/octet-stream"
,
".bmp" : "image/bmp"
,
".bz2" : "application/x-bzip2"
,
".c" : "text/x-c"
,
".cab" : "application/vnd.ms-cab-compressed"
,
".cc" : "text/x-c"
,
".chm" : "application/vnd.ms-htmlhelp"
,
".class" : "application/octet-stream"
,
".com" : "application/x-msdownload"
,
".conf" : "text/plain"
,
".cpp" : "text/x-c"
,
".crt" : "application/x-x509-ca-cert"
,
".css" : "text/css"
,
".csv" : "text/csv"
,
".cxx" : "text/x-c"
,
".deb" : "application/x-debian-package"
,
".der" : "application/x-x509-ca-cert"
,
".diff" : "text/x-diff"
,
".djv" : "image/vnd.djvu"
,
".djvu" : "image/vnd.djvu"
,
".dll" : "application/x-msdownload"
,
".dmg" : "application/octet-stream"
,
".doc" : "application/msword"
,
".dot" : "application/msword"
,
".dtd" : "application/xml-dtd"
,
".dvi" : "application/x-dvi"
,
".ear" : "application/java-archive"
,
".eml" : "message/rfc822"
,
".eps" : "application/postscript"
,
".exe" : "application/x-msdownload"
,
".f" : "text/x-fortran"
,
".f77" : "text/x-fortran"
,
".f90" : "text/x-fortran"
,
".flv" : "video/x-flv"
,
".for" : "text/x-fortran"
,
".gem" : "application/octet-stream"
,
".gemspec" : "text/x-script.ruby"
,
".gif" : "image/gif"
,
".gz" : "application/x-gzip"
,
".h" : "text/x-c"
,
".hh" : "text/x-c"
,
".htm" : "text/html"
,
".html" : "text/html"
,
".ico" : "image/vnd.microsoft.icon"
,
".ics" : "text/calendar"
,
".ifb" : "text/calendar"
,
".iso" : "application/octet-stream"
,
".jar" : "application/java-archive"
,
".java" : "text/x-java-source"
,
".jnlp" : "application/x-java-jnlp-file"
,
".jpeg" : "image/jpeg"
,
".jpg" : "image/jpeg"
,
".js" : "application/javascript;charset=utf-8"
,
".json" : "application/json"
,
".log" : "text/plain;charset=utf-8"
,
".m3u" : "audio/x-mpegurl"
,
".m4v" : "video/mp4"
,
".man" : "text/troff"
,
".mathml" : "application/mathml+xml"
,
".mbox" : "application/mbox"
,
".mdoc" : "text/troff"
,
".me" : "text/troff"
,
".mid" : "audio/midi"
,
".midi" : "audio/midi"
,
".mime" : "message/rfc822"
,
".mml" : "application/mathml+xml"
,
".mng" : "video/x-mng"
,
".mov" : "video/quicktime"
,
".mp3" : "audio/mpeg"
,
".mp4" : "video/mp4"
,
".mp4v" : "video/mp4"
,
".mpeg" : "video/mpeg"
,
".mpg" : "video/mpeg"
,
".ms" : "text/troff"
,
".msi" : "application/x-msdownload"
,
".odp" : "application/vnd.oasis.opendocument.presentation"
,
".ods" : "application/vnd.oasis.opendocument.spreadsheet"
,
".odt" : "application/vnd.oasis.opendocument.text"
,
".ogg" : "application/ogg"
,
".p" : "text/x-pascal"
,
".pas" : "text/x-pascal"
,
".pbm" : "image/x-portable-bitmap"
,
".pdf" : "application/pdf"
,
".pem" : "application/x-x509-ca-cert"
,
".pgm" : "image/x-portable-graymap"
,
".pgp" : "application/pgp-encrypted"
,
".pkg" : "application/octet-stream"
,
".pl" : "text/x-script.perl"
,
".pm" : "text/x-script.perl-module"
,
".png" : "image/png"
,
".pnm" : "image/x-portable-anymap"
,
".ppm" : "image/x-portable-pixmap"
,
".pps" : "application/vnd.ms-powerpoint"
,
".ppt" : "application/vnd.ms-powerpoint"
,
".ps" : "application/postscript"
,
".psd" : "image/vnd.adobe.photoshop"
,
".py" : "text/x-script.python"
,
".qt" : "video/quicktime"
,
".ra" : "audio/x-pn-realaudio"
,
".rake" : "text/x-script.ruby"
,
".ram" : "audio/x-pn-realaudio"
,
".rar" : "application/x-rar-compressed"
,
".rb" : "text/x-script.ruby"
,
".rdf" : "application/rdf+xml"
,
".roff" : "text/troff"
,
".rpm" : "application/x-redhat-package-manager"
,
".rss" : "application/rss+xml"
,
".rtf" : "application/rtf"
,
".ru" : "text/x-script.ruby"
,
".s" : "text/x-asm"
,
".sgm" : "text/sgml"
,
".sgml" : "text/sgml"
,
".sh" : "application/x-sh"
,
".sig" : "application/pgp-signature"
,
".snd" : "audio/basic"
,
".so" : "application/octet-stream"
,
".svg" : "image/svg+xml"
,
".svgz" : "image/svg+xml"
,
".swf" : "application/x-shockwave-flash"
,
".t" : "text/troff"
,
".tar" : "application/x-tar"
,
".tbz" : "application/x-bzip-compressed-tar"
,
".tcl" : "application/x-tcl"
,
".tex" : "application/x-tex"
,
".texi" : "application/x-texinfo"
,
".texinfo" : "application/x-texinfo"
,
".text" : "text/plain"
,
".tif" : "image/tiff"
,
".tiff" : "image/tiff"
,
".torrent" : "application/x-bittorrent"
,
".tr" : "text/troff"
,
".txt" : "text/plain"
,
".vcf" : "text/x-vcard"
,
".vcs" : "text/x-vcalendar"
,
".vrml" : "model/vrml"
,
".war" : "application/java-archive"
,
".wav" : "audio/x-wav"
,
".wma" : "audio/x-ms-wma"
,
".wmv" : "video/x-ms-wmv"
,
".wmx" : "video/x-ms-wmx"
,
".wrl" : "model/vrml"
,
".wsdl" : "application/wsdl+xml"
,
".xbm" : "image/x-xbitmap"
,
".xhtml" : "application/xhtml+xml"
,
".xls" : "application/vnd.ms-excel"
,
".xml" : "application/xml"
,
".xpm" : "image/x-xpixmap"
,
".xsl" : "application/xml"
,
".xslt" : "application/xslt+xml"
,
".yaml" : "text/yaml"
,
".yml" : "text/yaml"
,
".zip" : "application/zip"
}
};

exports.mime
=mime;