root / HServer / 00.Server / 00.Program / node_modules / mv / index.js
이력 | 보기 | 이력해설 | 다운로드 (2.47 KB)
1 | 39 | HKM | 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 | } |