You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Node.js脚本定时监测文件夹并自动上传图片至API?

Node.js 实现方案

方法1:文件实时监听(高效推荐)

用chokidar库监听文件夹新增文件,无需定时轮询,响应更及时。

操作步骤:

  1. 安装依赖:
npm install chokidar axios
  1. 实现代码:
const chokidar = require('chokidar');
const axios = require('axios');
const fs = require('fs');
const path = require('path');

// 配置参数
const WATCH_DIR = './watch-folder'; // 目标监测文件夹
const UPLOAD_API = 'https://localhost:4200/images';
const PROCESSED_RECORD = './processed-files.json'; // 记录已上传文件,避免重复操作

// 初始化已处理文件集合
let processedFiles = new Set();
if (fs.existsSync(PROCESSED_RECORD)) {
  processedFiles = new Set(JSON.parse(fs.readFileSync(PROCESSED_RECORD, 'utf8')));
}

// 保存已处理文件记录
const saveRecord = () => {
  fs.writeFileSync(PROCESSED_RECORD, JSON.stringify([...processedFiles]));
};

// 文件上传逻辑
const uploadFile = async (filePath) => {
  try {
    const formData = new FormData();
    formData.append('image', fs.createReadStream(filePath));

    const response = await axios.post(UPLOAD_API, formData, {
      headers: { ...formData.getHeaders() }
    });

    console.log(`文件 ${path.basename(filePath)} 上传成功:`, response.data);
    processedFiles.add(filePath);
    saveRecord();
  } catch (err) {
    console.error(`文件 ${path.basename(filePath)} 上传失败:`, err.message);
  }
};

// 启动文件夹监听
const watcher = chokidar.watch(WATCH_DIR, {
  ignored: /^\./, // 忽略隐藏文件
  persistent: true,
  ignoreInitial: false // 启动时扫描已有文件(可选)
});

// 监听新增文件事件
watcher.on('add', async (filePath) => {
  const ext = path.extname(filePath).toLowerCase();
  // 仅处理图片格式
  if (['.jpg', '.jpeg', '.png', '.gif'].includes(ext) && !processedFiles.has(filePath)) {
    await uploadFile(filePath);
  }
});

watcher.on('error', (err) => console.error('监听出错:', err));
console.log(`已开始监测文件夹: ${WATCH_DIR}`);

方法2:定时轮询(轻量简单)

无需第三方库,定时扫描文件夹对比文件状态:

const fs = require('fs');
const path = require('path');
const axios = require('axios');

const WATCH_DIR = './watch-folder';
const UPLOAD_API = 'https://localhost:4200/images';
const CHECK_INTERVAL = 5000; // 5秒轮询一次
let processedFiles = new Set();

const scanAndUpload = async () => {
  try {
    const files = fs.readdirSync(WATCH_DIR).map(file => path.join(WATCH_DIR, file));
    
    // 筛选新增图片文件
    const newFiles = files.filter(file => {
      const ext = path.extname(file).toLowerCase();
      return ['jpg', 'jpeg', 'png', 'gif'].includes(ext) && !processedFiles.has(file);
    });

    for (const file of newFiles) {
      const formData = new FormData();
      formData.append('image', fs.createReadStream(file));
      
      await axios.post(UPLOAD_API, formData, {
        headers: formData.getHeaders()
      });
      
      console.log(`文件 ${path.basename(file)} 上传成功`);
      processedFiles.add(file);
    }
  } catch (err) {
    console.error('轮询上传出错:', err.message);
  }
};

// 初始扫描
scanAndUpload();
// 启动定时任务
setInterval(scanAndUpload, CHECK_INTERVAL);
console.log(`已启动定时轮询,间隔 ${CHECK_INTERVAL/1000} 秒`);

PHP 实现方案

PHP本身是单请求运行模式,需结合Crontab定时任务实现定时扫描上传。

操作步骤:

  1. 编写上传脚本(upload-images.php):
<?php
// 配置参数
$watchDir = './watch-folder';
$uploadApi = 'https://localhost:4200/images';
$processedLog = './processed-files.log';

// 初始化已处理文件列表
$processedFiles = [];
if (file_exists($processedLog)) {
    $processedFiles = file($processedLog, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
}
$processedFiles = array_flip($processedFiles); // 转关联数组提升查询效率

// 扫描文件夹
$files = scandir($watchDir);
foreach ($files as $file) {
    $filePath = $watchDir . DIRECTORY_SEPARATOR . $file;
    
    // 跳过目录和隐藏文件
    if (is_dir($filePath) || str_starts_with($file, '.')) {
        continue;
    }
    
    // 仅处理图片格式
    $ext = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
    if (!in_array($ext, ['jpg', 'jpeg', 'png', 'gif'])) {
        continue;
    }
    
    // 跳过已处理文件
    if (isset($processedFiles[$filePath])) {
        continue;
    }
    
    // 执行上传
    $ch = curl_init();
    $cfile = new CURLFile($filePath);
    $postData = ['image' => $cfile];
    
    curl_setopt($ch, CURLOPT_URL, $uploadApi);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 本地测试可关闭,生产环境建议开启
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    
    if ($httpCode === 200) {
        echo "文件 {$file} 上传成功\n";
        // 记录已处理文件
        file_put_contents($processedLog, $filePath . PHP_EOL, FILE_APPEND);
    } else {
        echo "文件 {$file} 上传失败,HTTP状态码: {$httpCode}\n";
    }
    
    curl_close($ch);
}
?>
  1. 设置Crontab定时任务:
    打开终端输入crontab -e,添加以下配置(示例为每5分钟执行一次,可按需调整):
*/5 * * * * php /绝对路径/upload-images.php >> /绝对路径/upload-log.log 2>&1
  • */5 * * * *:代表每5分钟执行一次
  • /绝对路径/upload-images.php:替换为脚本的实际绝对路径
  • >> /绝对路径/upload-log.log 2>&1:将执行日志写入文件,便于排查问题

内容的提问来源于stack exchange,提问作者kate moss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 18:36:41