|
@@ -0,0 +1,101 @@
|
|
|
|
|
+import fs from 'fs';
|
|
|
|
|
+import archiver from 'archiver';
|
|
|
|
|
+import { exec } from 'child_process';
|
|
|
|
|
+import { readdir, stat } from 'fs/promises';
|
|
|
|
|
+
|
|
|
|
|
+export function readFileRange(file, start, length) {
|
|
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
|
|
+ fs.open(file, 'r', (err, fd) => {
|
|
|
|
|
+ if (err) {
|
|
|
|
|
+ reject('Error opening file:', er);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ const buffer = Buffer.alloc(length);
|
|
|
|
|
+ fs.read(fd, buffer, 0, length, start, (err, bytesRead, buffer) => {
|
|
|
|
|
+ if (err) {
|
|
|
|
|
+ reject('Error reading file:', err)
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ fs.close(fd, (err) => {
|
|
|
|
|
+ if (err) {
|
|
|
|
|
+ reject('Error closing file:', err)
|
|
|
|
|
+ return ;
|
|
|
|
|
+ }
|
|
|
|
|
+ resolve(buffer);
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+export function pad(num, n) {
|
|
|
|
|
+ var strNum = num.toString();
|
|
|
|
|
+ var len = strNum.length;
|
|
|
|
|
+ while (len < n) {
|
|
|
|
|
+ strNum = "0" + strNum;
|
|
|
|
|
+ len++;
|
|
|
|
|
+ }
|
|
|
|
|
+ return strNum;
|
|
|
|
|
+}
|
|
|
|
|
+export function execAsync(command) {
|
|
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
|
|
+ console.log('[CMD] ' + command);
|
|
|
|
|
+ exec(command, (error, stdout, stderr) => {
|
|
|
|
|
+ if (error) {
|
|
|
|
|
+ reject(error);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ resolve(stdout);
|
|
|
|
|
+ });
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+export async function compressZip(dir, targetFilePath, skipFiles) {
|
|
|
|
|
+ const output = fs.createWriteStream(targetFilePath);
|
|
|
|
|
+ const archive = archiver('zip', {
|
|
|
|
|
+ zlib: { level: 9 } // Sets the compression level.
|
|
|
|
|
+ });
|
|
|
|
|
+ archive.pipe(output);
|
|
|
|
|
+
|
|
|
|
|
+ function checkPathSkip(pathString) {
|
|
|
|
|
+ if (!pathString)
|
|
|
|
|
+ return true;
|
|
|
|
|
+ if (pathString.startsWith('.') || pathString.startsWith('/.'))
|
|
|
|
|
+ return true;
|
|
|
|
|
+ if (!skipFiles || skipFiles.length === 0)
|
|
|
|
|
+ return;
|
|
|
|
|
+ return skipFiles.find((item) => pathString.startsWith(item) || pathString.startsWith(`/${item}`));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async function loopDir(path, subPrefix) {
|
|
|
|
|
+ const files = await readdir(path);
|
|
|
|
|
+ for (const file of files) {
|
|
|
|
|
+ const subPath = subPrefix + '/' + file;
|
|
|
|
|
+ if (checkPathSkip(subPath))
|
|
|
|
|
+ continue;
|
|
|
|
|
+ console.log('File: ' + subPath);
|
|
|
|
|
+ const filestat = await stat(dir + subPath);
|
|
|
|
|
+ if (filestat.isDirectory()) {
|
|
|
|
|
+ await loopDir(dir + subPath, subPath);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ archive.file(dir + subPath, { name: subPath });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ await loopDir(dir, '')
|
|
|
|
|
+
|
|
|
|
|
+ console.log('等待压缩zip...');
|
|
|
|
|
+
|
|
|
|
|
+ const waitArchive = new Promise((resolve, reject) => {
|
|
|
|
|
+ output.on('close', function() {
|
|
|
|
|
+ console.log(archive.pointer() + ' total bytes');
|
|
|
|
|
+ console.log('archiver has been finalized and the output file descriptor has closed.');
|
|
|
|
|
+ resolve();
|
|
|
|
|
+ });
|
|
|
|
|
+ archive.on('error', function(err) {
|
|
|
|
|
+ reject(err);
|
|
|
|
|
+ });
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ await archive.finalize();
|
|
|
|
|
+ await waitArchive;
|
|
|
|
|
+}
|