node.js中的fs.realpath方法使用说明
方法说明:
获取真实路径。
可以使用process.cwd解决相对路径。
语法:
fs.realpath(path,[cache],[callback(err,resolvedPath)])
由于该方法属于fs模块,使用前需要引入fs模块(varfs=require(“fs”))
接收参数:
path 路径
cache 可选,一个文字的映射路径可用于强制一个特定的路径解决或避免额外的fs.stat需要知道真正的路径对象。
callback 回调
err 异常
resolvedPath 真实地址
例子:
varcache={'/etc':'/private/etc'};
fs.realpath('/etc/passwd',cache,function(err,resolvedPath){
if(err)throwerr;
console.log(resolvedPath);
});
源码:
fs.realpath=functionrealpath(p,cache,cb){
if(!util.isFunction(cb)){
cb=maybeCallback(cache);
cache=null;
}
//makepisabsolute
p=pathModule.resolve(p);
if(cache&&Object.prototype.hasOwnProperty.call(cache,p)){
returnprocess.nextTick(cb.bind(null,null,cache[p]));
}
varoriginal=p,
seenLinks={},
knownHard={};
//currentcharacterpositioninp
varpos;
//thepartialpathsofar,includingatrailingslashifany
varcurrent;
//thepartialpathwithoutatrailingslash(exceptwhenpointingataroot)
varbase;
//thepartialpathscannedinthepreviousround,withslash
varprevious;
start();
functionstart(){
//Skipoverroots
varm=splitRootRe.exec(p);
pos=m[0].length;
current=m[0];
base=m[0];
previous='';
//Onwindows,checkthattherootexists.Onunixthereisnoneed.
if(isWindows&&!knownHard[base]){
fs.lstat(base,function(err){
if(err)returncb(err);
knownHard[base]=true;
LOOP();
});
}else{
process.nextTick(LOOP);
}
}
//walkdownthepath,swappingoutlinkedpathpartsfortheirreal
//values
functionLOOP(){
//stopifscannedpastendofpath
if(pos>=p.length){
if(cache)cache[original]=p;
returncb(null,p);
}
//findthenextpart
nextPartRe.lastIndex=pos;
varresult=nextPartRe.exec(p);
previous=current;
current+=result[0];
base=previous+result[1];
pos=nextPartRe.lastIndex;
//continueifnotasymlink
if(knownHard[base]||(cache&&cache[base]===base)){
returnprocess.nextTick(LOOP);
}
if(cache&&Object.prototype.hasOwnProperty.call(cache,base)){
//knownsymboliclink.noneedtostatagain.
returngotResolvedLink(cache[base]);
}
returnfs.lstat(base,gotStat);
}
functiongotStat(err,stat){
if(err)returncb(err);
//ifnotasymlink,skiptothenextpathpart
if(!stat.isSymbolicLink()){
knownHard[base]=true;
if(cache)cache[base]=base;
returnprocess.nextTick(LOOP);
}
//stat&readthelinkifnotreadbefore
//callgotTargetassoonasthelinktargetisknown
//dev/inoalwaysreturn0onwindows,soskipthecheck.
if(!isWindows){
varid=stat.dev.toString(32)+':'+stat.ino.toString(32);
if(seenLinks.hasOwnProperty(id)){
returngotTarget(null,seenLinks[id],base);
}
}
fs.stat(base,function(err){
if(err)returncb(err);
fs.readlink(base,function(err,target){
if(!isWindows)seenLinks[id]=target;
gotTarget(err,target);
});
});
}
functiongotTarget(err,target,base){
if(err)returncb(err);
varresolvedLink=pathModule.resolve(previous,target);
if(cache)cache[base]=resolvedLink;
gotResolvedLink(resolvedLink);
}
functiongotResolvedLink(resolvedLink){
//resolvethelink,thenstartover
p=pathModule.resolve(resolvedLink,p.slice(pos));
start();
}
};