코드 복사 코드는 다음과 같습니다.
fs.realpath = 함수 realpath(p, 캐시, cb) {
if (!util.isFunction(cb)) {
cb = 어쩌면Callback(캐시);
캐시 = null;
}
// p를 절대값으로 설정
p = pathModule.resolve(p);
if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
return process.nextTick(cb.bind(null, null, 캐시[p]));
}
var 원본 = p,
seeLinks = {},
KnownHard = {};
// p의 현재 문자 위치
var pos;
// 지금까지의 부분 경로(있는 경우 후행 슬래시 포함)
var 전류;
// 후행 슬래시가 없는 부분 경로(루트를 가리키는 경우 제외)
var 베이스;
// 이전 라운드에서 스캔한 부분 경로(슬래시 포함)
var 이전;
시작();
함수 시작() {
// 루트 건너뛰기
var m = SplitRootRe.exec(p);
위치 = m[0].length;
전류 = m[0];
기본 = m[0];
이전 = '';
// Windows에서는 루트가 존재하는지 확인합니다. 유닉스에서는 필요하지 않습니다.
if (isWindows && !knownHard[base]) {
fs.lstat(base, function(err) {
if (err) return cb(err);
알려진 하드[베이스] = true;
루프();
});
} 그 밖의 {
process.nextTick(LOOP);
}
}
// 경로를 따라 걸어가면서 연결된 경로 부분을 실제 경로 부분으로 교체합니다
// 값
함수 LOOP() {
// 경로 끝을 지나 스캔되면 중지
if (pos >= p.length) {
if (캐시) 캐시[원본] = p;
return cb(null, p);
}
// 다음 부분 찾기
nextPartRe.lastIndex = pos;
var 결과 = nextPartRe.exec(p);
이전 = 현재;
현재 = 결과[0];
기본 = 이전 결과[1];
pos = nextPartRe.lastIndex;
// 심볼릭 링크가 아닌 경우 계속
if (knownHard[base] || (cache && 캐시[base] === base)) {
return process.nextTick(LOOP);
}
if (cache && Object.prototype.hasOwnProperty.call(cache, base)) {
// 알려진 심볼릭 링크. 다시 통계를 낼 필요가 없습니다.
return gotResolvedLink(cache[base]);
}
return fs.lstat(base, gotStat);
}
함수 gotStat(err, stat) {
if (err) return cb(err);
// 심볼릭 링크가 아닌 경우 다음 경로 부분으로 건너뜁니다
if (!stat.isSymbolicLink()) {
알려진 하드[베이스] = true;
if (캐시) 캐시[베이스] = 베이스;
return process.nextTick(LOOP);
}
// 이전에 읽지 않았다면 링크를 통계하고 읽습니다
// 링크 타겟이 알려지면 즉시 gotTarget을 호출하세요
// dev/ino는 Windows에서 항상 0을 반환하므로 확인을 건너뜁니다.
if (!isWindows) {
var id = stat.dev.toString(32) ':' stat.ino.toString(32);
if (seenLinks.hasOwnProperty(id)) {
return gotTarget(null, seeLinks[id], base);
}
}
fs.stat(base, function(err) {
if (err) return cb(err);
fs.readlink(base, function(err, target) {
if (!isWindows) visibleLinks[id] = 대상;
gotTarget(err, target);
});
});
}
function gotTarget(err, target, base) {
if (err) return cb(err);
var receivedLink = pathModule.resolve(이전, 대상);
if (캐시) 캐시[베이스] = 해결링크;
gotResolvedLink(resolvedLink);
}
함수 gotResolvedLink(resolvedLink) {
// 링크를 해결한 후 다시 시작하세요
p = pathModule.resolve(resolvedLink, p.slice(pos));
시작();
}
};