-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathsplit.js
74 lines (68 loc) · 1.81 KB
/
split.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
const Promise = require('bluebird');
const fs = Promise.promisifyAll(require("fs"));
/**
* Split a big file to small pieces
* @param {string} filePath the absolute file path.
* @param {number} partSize the file size of one piece.
*/
function split(filePath, partSize) {
return Promise
.resolve({
filePath: filePath,
partSize: partSize * 1024
})
.then(getFileStats)
.then(caculate)
.then(doSplit)
.catch(Promise.reject);
}
function getFileStats(params) {
params.stats = fs.lstatAsync(params.filePath)
return Promise.props(params);
}
function caculate(params) {
const fileSize = params.stats.size;
const partSize = params.partSize;
if (fileSize < partSize) {
return Promise.reject('FILE_TOO_SMALL');
}
const parts = Math.ceil(parseFloat(fileSize) / parseFloat(partSize));
params.fileSize = fileSize;
params.parts = parts;
delete params.stats;
return params;
}
function doSplit(params) {
const partSize = params.partSize;
const fileSize = params.fileSize;
const filePath = params.filePath;
const parts = params.parts;
const promises = [];
for (let i = 0; i < parts; i++) {
const range = [];
range[0] = i * partSize;
range[1] = range[0] + partSize;
if (i == parts - 1) {
range[1] = fileSize;
}
promises.push(createSplit(filePath, range, filePath + '_' + i));
}
return Promise.all(promises);
}
function createSplit(filePath, range, newFilePath) {
return new Promise((resolve, reject) => {
const rStream = fs.createReadStream(filePath, {
flags: 'r',
start: range[0],
end: range[1],
autoClose: true
});
const wStream = fs.createWriteStream(newFilePath);
rStream.pipe(wStream);
rStream.on('end', () => {
wStream.end();
resolve(newFilePath);
})
});
}
module.exports = split;