root / HServer / 00.Server / 00.Program / node_modules / mv / index.js
이력 | 보기 | 이력해설 | 다운로드 (2.47 KB)
1 |
var fs = require('fs'); |
---|---|
2 |
var ncp = require('ncp').ncp; |
3 |
var path = require('path'); |
4 |
var rimraf = require('rimraf'); |
5 |
var mkdirp = require('mkdirp'); |
6 |
|
7 |
module.exports = mv; |
8 |
|
9 |
function mv(source, dest, options, cb){ |
10 |
if (typeof options === 'function') { |
11 |
cb = options; |
12 |
options = {}; |
13 |
} |
14 |
var shouldMkdirp = !!options.mkdirp;
|
15 |
var clobber = options.clobber !== false; |
16 |
var limit = options.limit || 16; |
17 |
|
18 |
if (shouldMkdirp) {
|
19 |
mkdirs(); |
20 |
} else {
|
21 |
doRename(); |
22 |
} |
23 |
|
24 |
function mkdirs() { |
25 |
mkdirp(path.dirname(dest), function(err) {
|
26 |
if (err) return cb(err); |
27 |
doRename(); |
28 |
}); |
29 |
} |
30 |
|
31 |
function doRename() { |
32 |
if (clobber) {
|
33 |
fs.rename(source, dest, function(err) {
|
34 |
if (!err) return cb(); |
35 |
if (err.code !== 'EXDEV') return cb(err); |
36 |
moveFileAcrossDevice(source, dest, clobber, limit, cb); |
37 |
}); |
38 |
} else {
|
39 |
fs.link(source, dest, function(err) {
|
40 |
if (err) {
|
41 |
if (err.code === 'EXDEV') { |
42 |
moveFileAcrossDevice(source, dest, clobber, limit, cb); |
43 |
return;
|
44 |
} |
45 |
if (err.code === 'EISDIR' || err.code === 'EPERM') { |
46 |
moveDirAcrossDevice(source, dest, clobber, limit, cb); |
47 |
return;
|
48 |
} |
49 |
cb(err); |
50 |
return;
|
51 |
} |
52 |
fs.unlink(source, cb); |
53 |
}); |
54 |
} |
55 |
} |
56 |
} |
57 |
|
58 |
function moveFileAcrossDevice(source, dest, clobber, limit, cb) { |
59 |
var outFlags = clobber ? 'w' : 'wx'; |
60 |
var ins = fs.createReadStream(source);
|
61 |
var outs = fs.createWriteStream(dest, {flags: outFlags}); |
62 |
ins.on('error', function(err){ |
63 |
ins.destroy(); |
64 |
outs.destroy(); |
65 |
outs.removeListener('close', onClose);
|
66 |
if (err.code === 'EISDIR' || err.code === 'EPERM') { |
67 |
moveDirAcrossDevice(source, dest, clobber, limit, cb); |
68 |
} else {
|
69 |
cb(err); |
70 |
} |
71 |
}); |
72 |
outs.on('error', function(err){ |
73 |
ins.destroy(); |
74 |
outs.destroy(); |
75 |
outs.removeListener('close', onClose);
|
76 |
cb(err); |
77 |
}); |
78 |
outs.once('close', onClose);
|
79 |
ins.pipe(outs); |
80 |
function onClose(){ |
81 |
fs.unlink(source, cb); |
82 |
} |
83 |
} |
84 |
|
85 |
function moveDirAcrossDevice(source, dest, clobber, limit, cb) { |
86 |
var options = {
|
87 |
stopOnErr: true, |
88 |
clobber: false, |
89 |
limit: limit,
|
90 |
}; |
91 |
if (clobber) {
|
92 |
rimraf(dest, { disableGlob: true }, function(err) { |
93 |
if (err) return cb(err); |
94 |
startNcp(); |
95 |
}); |
96 |
} else {
|
97 |
startNcp(); |
98 |
} |
99 |
function startNcp() { |
100 |
ncp(source, dest, options, function(errList) {
|
101 |
if (errList) return cb(errList[0]); |
102 |
rimraf(source, { disableGlob: true }, cb); |
103 |
}); |
104 |
} |
105 |
} |