使用pako和base64实现文本压缩、解压,保证压缩后输出内容依旧是文本
import { deflate, inflate } from "pako";
import {
readFileSync,
writeFileSync,
existsSync,
mkdirSync,
readdirSync,
statSync,
} from "fs";
import { join, dirname, basename, extname } from "path";
// 判断操作类型和路径
const operation = process.argv[2]; // c 或 d
const inputPath = process.argv[3];
if (!operation || !inputPath) {
console.error("Usage: node index.js [c|d] <folder_path>");
process.exit(1);
}
// 处理压缩操作
if (operation === "c") {
compressFolder(inputPath);
}
// 处理解压操作
else if (operation === "d") {
decompressFolder(inputPath);
} else {
console.error(
"Invalid operation. Use 'c' for compress or 'd' for decompress"
);
process.exit(1);
}
// 压缩文件夹
function compressFolder(folderPath) {
if (!existsSync(folderPath)) {
console.error(`Folder ${folderPath} does not exist`);
process.exit(1);
}
const outputFolder = folderPath + "_compressed";
if (!existsSync(outputFolder)) {
mkdirSync(outputFolder, { recursive: true });
}
processFolder(folderPath, outputFolder, (filePath, outputPath) => {
try {
// 读取文件内容
const content = readFileSync(filePath, "utf-8");
// 压缩内容
const compressed = deflate(content, { to: "string" });
// 转换为base64字符串
const compressedString = Buffer.from(compressed).toString("base64");
// 写入压缩文件
const compressedFilePath = outputPath + ".compressed";
writeFileSync(compressedFilePath, compressedString, "utf-8");
console.log(`Compressed: ${filePath} -> ${compressedFilePath}`);
} catch (error) {
console.error(`Error compressing ${filePath}:`, error.message);
}
});
}
// 解压文件夹
function decompressFolder(folderPath) {
if (!existsSync(folderPath)) {
console.error(`Folder ${folderPath} does not exist`);
process.exit(1);
}
// 修改输出目录逻辑:在输入目录的同级创建解压目录
const baseName = basename(folderPath);
const dirName = dirname(folderPath);
const outputFolder = join(
dirName,
baseName.replace(/_compressed$/, "") + "_decompressed"
);
if (!existsSync(outputFolder)) {
mkdirSync(outputFolder, { recursive: true });
}
processFolder(folderPath, outputFolder, (filePath, outputPath) => {
// 只处理压缩文件
if (filePath.endsWith(".compressed")) {
try {
// 读取压缩文件内容
const compressedData = readFileSync(filePath, "utf-8");
// 解码base64
const compressedBuffer = Buffer.from(compressedData, "base64");
// 解压内容
const decompressed = inflate(compressedBuffer, { to: "string" });
// 移除 .compressed 扩展名
const decompressedFilePath = outputPath.replace(/\.compressed$/, "");
writeFileSync(decompressedFilePath, decompressed, "utf-8");
console.log(`Decompressed: ${filePath} -> ${decompressedFilePath}`);
} catch (error) {
console.error(`Error decompressing ${filePath}:`, error.message);
}
}
});
}
// 遍历文件夹并处理文件
function processFolder(inputFolder, outputFolder, processFileFn) {
function walkDir(currentInputPath, currentOutputPath) {
const items = readdirSync(currentInputPath);
for (const item of items) {
const inputItemPath = join(currentInputPath, item);
const outputItemPath = join(currentOutputPath, item);
const stats = statSync(inputItemPath);
if (stats.isDirectory()) {
// 创建对应的输出目录
const newOutputPath = outputItemPath;
if (!existsSync(newOutputPath)) {
mkdirSync(newOutputPath, { recursive: true });
}
// 递归处理子目录
walkDir(inputItemPath, newOutputPath);
} else if (stats.isFile()) {
// 处理文件
processFileFn(inputItemPath, outputItemPath);
}
}
}
walkDir(inputFolder, outputFolder);
}使用方法:
- 安装依赖:
npm install pako - 压缩:
node index.js c <folder_path> - 解压:
node index.js d <folder_path>