node.js中的fs.realpath方法使用说明

  方法说明:

  获取真实路径。

  可以使用process.cwd解决相对路径。

  语法:

  

复制代码 代码如下:

  fs.realpath(path, [cache], [callback(err , resolvedPath)])

  由于该方法属于fs模块,使用前需要引入fs模块(var fs= require(“fs”) )

  接收参数:

  path                             路径

  cache                           可选,一个文字的映射路径可用于强制一个特定的路径解决或避免额外的fs.stat需要知道真正的路径对象。

  callback                       回调

  err                                异常

  resolvedPath               真实地址

  例子:

  

复制代码 代码如下:

  var cache = {'/etc':'/private/etc'};

  fs.realpath('/etc/passwd', cache, function (err, resolvedPath) {

  if (err) throw err;

  console.log(resolvedPath);

  });

  源码:

  

复制代码 代码如下:

  fs.realpath = function realpath(p, cache, cb) {

  if (!util.isFunction(cb)) {

  cb = maybeCallback(cache);

  cache = null;

  }

  // make p is absolute

  p = pathModule.resolve(p);

  if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {

  return process.nextTick(cb.bind(null, null, cache[p]));

  }

  var original = p,

  seenLinks = {},

  knownHard = {};

  // current character position in p

  var pos;

  // the partial path so far, including a trailing slash if any

  var current;

  // the partial path without a trailing slash (except when pointing at a root)

  var base;

  // the partial path scanned in the previous round, with slash

  var previous;

  start();

  function start() {

  // Skip over roots

  var m = splitRootRe.exec(p);

  pos = m[0].length;

  current = m[0];

  base = m[0];

  previous = '';

  // On windows, check that the root exists. On unix there is no need.

  if (isWindows && !knownHard[base]) {

  fs.lstat(base, function(err) {

  if (err) return cb(err);

  knownHard[base] = true;

  LOOP();

  });

  } else {

  process.nextTick(LOOP);

  }

  }

  // walk down the path, swapping out linked pathparts for their real

  // values

  function LOOP() {

  // stop if scanned past end of path

  if (pos >= p.length) {

  if (cache) cache[original] = p;

  return cb(null, p);

  }

  // find the next part

  nextPartRe.lastIndex = pos;

  var result = nextPartRe.exec(p);

  previous = current;

  current += result[0];

  base = previous + result[1];

  pos = nextPartRe.lastIndex;

  // continue if not a symlink

  if (knownHard[base] || (cache && cache[base] === base)) {

  return process.nextTick(LOOP);

  }

  if (cache && Object.prototype.hasOwnProperty.call(cache, base)) {

  // known symbolic link. no need to stat again.

  return gotResolvedLink(cache[base]);

  }

  return fs.lstat(base, gotStat);

  }

  function gotStat(err, stat) {

  if (err) return cb(err);

  // if not a symlink, skip to the next path part

  if (!stat.isSymbolicLink()) {

  knownHard[base] = true;

  if (cache) cache[base] = base;

  return process.nextTick(LOOP);

  }

  // stat & read the link if not read before

  // call gotTarget as soon as the link target is known

  // dev/ino always return 0 on windows, so skip the check.

  if (!isWindows) {

  var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);

  if (seenLinks.hasOwnProperty(id)) {

  return gotTarget(null, seenLinks[id], base);

  }

  }

  fs.stat(base, function(err) {

  if (err) return cb(err);

  fs.readlink(base, function(err, target) {

  if (!isWindows) seenLinks[id] = target;

  gotTarget(err, target);

  });

  });

  }

  function gotTarget(err, target, base) {

  if (err) return cb(err);

  var resolvedLink = pathModule.resolve(previous, target);

  if (cache) cache[base] = resolvedLink;

  gotResolvedLink(resolvedLink);

  }

  function gotResolvedLink(resolvedLink) {

  // resolve the link, then start over

  p = pathModule.resolve(resolvedLink, p.slice(pos));

  start();

  }

  };