Nodejs文件解压、过滤、打包+IP地址获取

一、模块导入
// ---------------------------<<导入模块>>---------------------------
const fs = require("fs");
const os = require("os");
const path = require("path");
const cors = require("cors");
const archiver = require("archiver");
const AdmZip = require('adm-zip');
const multer = require('multer');
const express = require("express");


// ---------------------------<<模块应用>>---------------------------
// 应用Express
const app = express();
// 设置multer存储
const upload = multer({ storage: multer.memoryStorage() });
// 设置跨域(*)
app.use(cors());

二、逻辑处理
// ---------------------------<<逻辑处理>>---------------------------
// 查找最新子文件夹
function findNewDir(dir, time) {
  const dirList = fs.readdirSync(dir);

  let newDir = null,
    lastTime = 0;

  for (let i = 0; i < dirList.length; i++) {
    var fullPath = path.join(dir, dirList[i]);
    const stat = fs.statSync(fullPath);

    if (stat.isDirectory()) {
      if (stat.birthtimeMs > lastTime) {
        lastTime = stat.birthtimeMs;
        newDir = fullPath;
      }
    }
  }

  if (lastTime > time) {
    return newDir;
  } else {
    return "";
  }
}

// 递归查找子文件夹下所有文件
function redFiles(dir, fileList = []) {
  const files = fs.readdirSync(dir);
  for (let i = 0; i < files.length; i++) {
    var fullPath = path.join(dir, files[i]);
    const stat = fs.statSync(fullPath);

    if (stat.isDirectory()) {
      redFiles(fullPath, fileList);
    } else {
      fileList.push(fullPath);
    }
  }

  return fileList;
}

// 获取并压缩文件
function findFile(files, res) {
  // 如果没有文件,则直接返回错误
  if (!files || files.length === 0) {
    return res.status(400).send('No files to zip.');
  }

  try {
    // 设置压缩级别
    const archive = archiver("zip", {
      zlib: { level: 9 },
    });

    // 注册 error 事件监听器,在 finalize() 之前进行
    archive.on("error", (err) => {
      console.error("创建 ZIP 文件时出错:", err);
      res.status(500).send("服务器错误");
    });

    // 添加文件到归档
    for (let i = 0; i < files.length; i++) {
      archive.file(files[i], { name: path.basename(files[i]) });
    }

    // 最终化归档
    archive.finalize();

    // 设定默认文件名
    res.attachment("files.zip");

    // 将归档流管道到响应对象
    archive.pipe(res);

  } catch (error) {
    console.error("处理请求时出错:", error);
    res.status(500).send("服务器错误");
  }
}

// 过滤xml文件
function findXml(newDir) {
  // 递归获取所有文件路径
  const result = redFiles(newDir, []);

  // 筛选掉所有非.xml文件
  let temp = [];
  const regex = /\.xml$/;
  for (let i = 0; i < result.length; i++) {
    // 筛选.xml文件
    if (regex.test(result[i])) {
      temp.push(result[i]);
    }
  }
  return temp
}

// 解压文件
function unzipFile(file, filename, res) {
  // *****注意:windows和linux的路径不一样,找一个固定路径处理文件解压和打包*****
  let directory = "/usr/local/src/temp"

  try {
    const zip = new AdmZip(file);
    zip.extractAllTo(directory, true); // true 表示覆盖已存在的文件
    console.log("")
    console.log('Files extracted successfully.');

    // 过滤所有xml文件
    let temp = findXml(directory)

    // 读取文件并压缩,返回结果给前端
    if (temp.length == 0) {
      return res.status(400).send('No files to zip.');
    } else {
      findFile(temp, res);
    }
  } catch (err) {
    console.error("处理请求时出错:", err);
    res.status(500).send("服务器错误");
  }
}

三、接口路由
// ---------------------------<<接口路由>>---------------------------
// 抓取文件
app.get("/getFiles", (req, res) => {
  // 获取接口参数
  let { startTime } = req.query;

  // *****注意:定义需要抓取的路径,也可以从接口传参*****
  let dir = '/usr/local/src'

  if (fs.existsSync(dir)) {

    // 获取最新文件夹并且时间小于开始时间
    let newDir = findNewDir(dir, startTime);

    if (newDir) {
      let temp = findXml(newDir)
      // 读取文件并压缩,返回结果给前端
      if (temp.length == 0) {
        return res.status(400).send('No files to zip.');
      } else {
        findFile(temp, res);
      }
    } else {//未找到文件夹
      return res.status(400).send('No search directory');
    }
  } else {
    res.send("")
  }
})

// 获取本机IP地址
app.get("/getLocalIp", (req, res) => {
  const interfaces = os.networkInterfaces();

  let ip = ''

  for (let key in interfaces) {
    for (let i = 0; i < interfaces[key].length; i++) {
      if (interfaces[key][i].family == 'IPv4' && !interfaces[key][i].internal) {
        ip = interfaces[key][i].address
      }
    }
  }

  if (ip) {
    return res.send({
      code: 1000,
      ip,
      msg: '请求成功'
    })
  } else {
    return res.send({
      code: 1001,
      ip,
      msg: '未找到IP'
    })
  }
});

// 重新打压缩包
app.post("/repackage", upload.single('file'), (req, res) => {
  if (!req.file) {
    return res.status(400).send('No file uploaded.');
  }

  unzipFile(req.file.buffer, res)
})

四、服务监听
// ---------------------------<<服务监听>>---------------------------
// 服务监端口
app.listen(9002, () => {
  console.log("服务已经启动,监听端口9002");
});

你可能感兴趣的:(前端,javascript)