33

我想删除任何超过一小时的文件。这是为了自动清理 tmp 上传目录。

这是我的代码:

fs.readdir( dirPath, function( err, files ) {
    if ( err ) return console.log( err );
    files.forEach(function( file ) {
        var filePath = dirPath + file;
        fs.stat( filePath, function( err, stat ) {
            if ( err ) return console.log( err );
            var livesUntil = new Date();
            livesUntil.setHours(livesUntil.getHours() - 1);
            if ( stat.ctime < livesUntil ) {
                fs.unlink( filePath, function( err ) {
                    if ( err ) return console.log( err );
                });
            }
        });
    });
});

但是,这只会删除目录中的所有内容,无论它是否在一小时前上传。

我是否误解了如何在 Node 中检查文件的年龄?

4

5 回答 5

34

我已经将find-remove用于类似的用例。

根据文档和您正在尝试做的事情,代码将是:

var findRemoveSync = require('find-remove');
findRemoveSync(__dirname + '/uploads', {age: {seconds: 3600}});

我实际上每 6 分钟运行一次,并通过执行以下操作删除超过 1 小时的文件:

setInterval(findRemoveSync.bind(this,__dirname + '/uploads', {age: {seconds: 3600}}), 360000)

请参阅示例,了解我如何使用 find-remove 清理/uploads文件夹。

于 2015-10-29T18:12:20.730 回答
25

我正在使用rimraf递归删除任何超过一小时的文件/文件夹。

根据文档,您应该在 ctime Date对象实例上使用getTime()以进行比较。

var uploadsDir = __dirname + '/uploads';

fs.readdir(uploadsDir, function(err, files) {
  files.forEach(function(file, index) {
    fs.stat(path.join(uploadsDir, file), function(err, stat) {
      var endTime, now;
      if (err) {
        return console.error(err);
      }
      now = new Date().getTime();
      endTime = new Date(stat.ctime).getTime() + 3600000;
      if (now > endTime) {
        return rimraf(path.join(uploadsDir, file), function(err) {
          if (err) {
            return console.error(err);
          }
          console.log('successfully deleted');
        });
      }
    });
  });
});
于 2014-04-11T20:58:36.463 回答
4

简单的递归解决方案仅删除所有文件!dirs 每 5 小时运行一次,删除 1 天的旧文件

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

setInterval(function() {
    walkDir('./tmpimages/', function(filePath) {
    fs.stat(filePath, function(err, stat) {
    var now = new Date().getTime();
    var endTime = new Date(stat.mtime).getTime() + 86400000; // 1days in miliseconds

    if (err) { return console.error(err); }

    if (now > endTime) {
        //console.log('DEL:', filePath);
      return fs.unlink(filePath, function(err) {
        if (err) return console.error(err);
      });
    }
  })  
});
}, 18000000); // every 5 hours



function walkDir(dir, callback) {
  fs.readdirSync(dir).forEach( f => {
    let dirPath = path.join(dir, f);
    let isDirectory = fs.statSync(dirPath).isDirectory();
    isDirectory ? 
      walkDir(dirPath, callback) : callback(path.join(dir, f));
  });
};

功能来源

于 2020-01-16T18:44:24.437 回答
1

看起来您正在将“stat.ctime”与整个 Date 对象进行比较。

if ( stat.ctime < livesUntil ) {

它不应该读:

if ( stat.ctime < livesUntil.getHours() ) {
于 2013-10-03T21:04:10.670 回答
1

由于本主题中的其他响应,我尝试创建自己的函数。它是一种打字稿样式,在 @NestJs 项目中使用类似于 Helper(此处用于 ExceptionHandling)。

依赖项

我也在使用

范围

  • parentDirectory:函数将遍历并删除所有早于的文件的目录60 hours
import * as path from 'path';
import * as fs from 'fs';
import * as moment from 'moment';
import { InternalServerErrorException } from '@nestjs/common';

export default function walk(parentDirectory: string): void {
  let list;
  let i = 0;

  try {
    // store list of all file and directory in the current directory
    list = fs.readdirSync(parentDirectory);
  } catch (e) {
    throw new InternalServerErrorException(e.toString());
  }

  return (function next() {
    const file = list[i++];

    if (file) {
      const filePath = path.resolve(parentDirectory, file);
      const stat = fs.statSync(filePath);

      if (stat && stat.isDirectory()) {
        // if it's a directory, continue walking
        walk(filePath);

        return next();
      } else {
        // see stats of the file for its creation date
        fs.stat(filePath, (err, stat) => {
          if (err) console.error(err);

          // using moment.js to compare expiration date
          const now = moment();
          const endTimeFile = moment(stat.ctimeMs).add(60, 'minutes');

          if (now > endTimeFile) {
            try {
              // delete file if expired
              fs.unlinkSync(filePath);
              console.log(`successfully deleted ${filePath}`);
            } catch (err) {
              throw new InternalServerErrorException(
                'file not deleted successfully',
              );
            }
          }
        });

        return next();
      }
    }
  })();
}

于 2021-04-21T08:43:05.463 回答