23

我正在尝试使用 Node.js 在目录中查找最近创建的文件,但似乎找不到解决方案。下面的代码似乎在一台机器上做了这个伎俩,但在另一台机器上它只是从目录中拉出一个随机文件 - 正如我想的那样。基本上,我需要找到最新的文件并且只有那个文件。

var fs = require('fs'); //File System
var audioFilePath = 'C:/scanner/audio/'; //Location of recorded audio files
    var audioFile = fs.readdirSync(audioFilePath)
        .slice(-1)[0]
        .replace('.wav', '.mp3');

非常感谢!

4

12 回答 12

29

假设underscore( http://underscorejs.org/ ) 的可用性并采用同步方法(它没有利用 node.js 的优势,但更容易掌握):

var fs = require('fs'),
    path = require('path'),
    _ = require('underscore');

// Return only base file name without dir
function getMostRecentFileName(dir) {
    var files = fs.readdirSync(dir);

    // use underscore for max()
    return _.max(files, function (f) {
        var fullpath = path.join(dir, f);

        // ctime = creation time is used
        // replace with mtime for modification time
        return fs.statSync(fullpath).ctime;
    });
}
于 2014-10-07T09:05:22.767 回答
6

另一种方法:

const glob = require('glob')

const newestFile = glob.sync('input/*xlsx')
  .map(name => ({name, ctime: fs.statSync(name).ctime}))
  .sort((a, b) => b.ctime - a.ctime)[0].name
于 2020-02-20T01:21:12.953 回答
6

虽然不是最有效的方法,但这在概念上应该是直截了当的:

var fs = require('fs'); //File System
var audioFilePath = 'C:/scanner/audio/'; //Location of recorded audio files
fs.readdir(audioFilePath, function(err, files) {
    if (err) { throw err; }
    var audioFile = getNewestFile(files, audioFilePath).replace('.wav', '.mp3');
    //process audioFile here or pass it to a function...
    console.log(audioFile);
});

function getNewestFile(files, path) {
    var out = [];
    files.forEach(function(file) {
        var stats = fs.statSync(path + "/" +file);
        if(stats.isFile()) {
            out.push({"file":file, "mtime": stats.mtime.getTime()});
        }
    });
    out.sort(function(a,b) {
        return b.mtime - a.mtime;
    })
    return (out.length>0) ? out[0].file : "";
}

顺便说一句,原始帖子中没有明显的理由使用同步文件列表。

于 2016-05-03T21:04:07.360 回答
5

功能更强大的版本可能如下所示:

import { readdirSync, lstatSync } from "fs";

const orderReccentFiles = (dir: string) =>
  readdirSync(dir)
    .filter(f => lstatSync(f).isFile())
    .map(file => ({ file, mtime: lstatSync(file).mtime }))
    .sort((a, b) => b.mtime.getTime() - a.mtime.getTime());

const getMostRecentFile = (dir: string) => {
  const files = orderReccentFiles(dir);
  return files.length ? files[0] : undefined;
};
于 2019-08-22T02:46:16.717 回答
4

首先,您需要订购文件(开头是最新的)

然后,获取最新文件的数组的第一个元素。

我已经修改了@mikeysee 的代码以避免路径异常,因此我使用完整路径来修复它们。

2个函数的截取代码如下所示。

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

const getMostRecentFile = (dir) => {
    const files = orderReccentFiles(dir);
    return files.length ? files[0] : undefined;
};

const orderReccentFiles = (dir) => {
    return fs.readdirSync(dir)
        .filter(file => fs.lstatSync(path.join(dir, file)).isFile())
        .map(file => ({ file, mtime: fs.lstatSync(path.join(dir, file)).mtime }))
        .sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
};

const dirPath = '<PATH>';
getMostRecentFile(dirPath)
于 2020-03-12T09:15:02.790 回答
3

这应该可以解决问题(“dir”是您使用 fs.readdir 获取“files”数组的目录):

function getNewestFile(dir, files, callback) {
    if (!callback) return;
    if (!files || (files && files.length === 0)) {
        callback();
    }
    if (files.length === 1) {
        callback(files[0]);
    }
    var newest = { file: files[0] };
    var checked = 0;
    fs.stat(dir + newest.file, function(err, stats) {
        newest.mtime = stats.mtime;
        for (var i = 0; i < files.length; i++) {
            var file = files[i];
            (function(file) {
                fs.stat(file, function(err, stats) {
                    ++checked;
                    if (stats.mtime.getTime() > newest.mtime.getTime()) {
                        newest = { file : file, mtime : stats.mtime };
                    }
                    if (checked == files.length) {
                        callback(newest);
                    }
                });
            })(dir + file);
        }
    });
 }
于 2014-07-20T18:57:22.053 回答
2

使用纯 JavaScript 和易于理解的结构:

function getLatestFile(dirpath) {

  // Check if dirpath exist or not right here

  let latest;

  const files = fs.readdirSync(dirpath);
  files.forEach(filename => {
    // Get the stat
    const stat = fs.lstatSync(path.join(dirpath, filename));
    // Pass if it is a directory
    if (stat.isDirectory())
      return;

    // latest default to first file
    if (!latest) {
      latest = {filename, mtime: stat.mtime};
      return;
    }
    // update latest if mtime is greater than the current latest
    if (stat.mtime > latest.mtime) {
      latest.filename = filename;
      latest.mtime = stat.mtime;
    }
  });

  return latest.filename;
}
于 2018-05-07T13:41:16.687 回答
2

[扩展 umair 的答案以纠正当前工作目录的错误]

function getNewestFile(dir, regexp) {
    var fs = require("fs"),
     path = require('path'),
    newest = null,
    files = fs.readdirSync(dir),
    one_matched = 0,
    i

    for (i = 0; i < files.length; i++) {

        if (regexp.test(files[i]) == false)
            continue
        else if (one_matched == 0) {
            newest = files[i];
            one_matched = 1;
            continue
        }

        f1_time = fs.statSync(path.join(dir, files[i])).mtime.getTime()
        f2_time = fs.statSync(path.join(dir, newest)).mtime.getTime()
        if (f1_time > f2_time)
            newest[i] = files[i]  
    }

    if (newest != null)
        return (path.join(dir, newest))
    return null
}
于 2016-03-13T21:53:39.597 回答
1

不幸的是,我认为不能保证这些文件按任何特定顺序排列。

相反,您需要在每个文件上调用fs.stat(或fs.statSync)以获取上次修改的日期,然后在获得所有日期后选择最新的日期。

于 2013-03-29T21:42:29.433 回答
1

令人惊讶的是,在这个问题中没有明确使用数组函数、函数式编程的例子。

这是我对在 nodejs 中获取目录的最新文件的看法。默认情况下,它将获取任何扩展名的最新文件。传递扩展属性时,该函数将返回该扩展的最新文件。

此代码的优点是它的声明性和模块化且易于理解,而不是使用“逻辑分支/控制流”,当然前提是您了解这些数组函数的工作原理

const fs = require('fs');
const path = require('path');
function getLatestFile({directory, extension}, callback){
  fs.readdir(directory, (_ , dirlist)=>{
    const latest = dirlist.map(_path => ({stat:fs.lstatSync(path.join(directory, _path)), dir:_path}))
      .filter(_path => _path.stat.isFile())
      .filter(_path => extension ? _path.dir.endsWith(`.${extension}`) : 1)
      .sort((a, b) => b.stat.mtime - a.stat.mtime)
      .map(_path => _path.dir);
    callback(latest[0]);
  });
}

getLatestFile({directory:process.cwd(), extension:'mp3'}, (filename=null)=>{
  console.log(filename);
});

于 2018-05-19T16:16:17.337 回答
0

@pguardiario 的功能答案的异步版本(我自己做了这个,然后在我去添加这个时在页面的中间找到了他们的答案)。

import {promisify} from  'util';
import _glob       from  'glob';
const glob = promisify(_glob);

const newestFile = (await Promise.all(
    (await glob(YOUR_GLOB)).map(async (file) => (
        {file, mtime:(await fs.stat(file)).mtime}
    ))
))
    .sort(({mtime:a}, {mtime:b}) => ((a < b) ? 1 : -1))
    [0]
    .file
;
于 2021-08-13T03:04:47.927 回答
0

读取目录 (fs.readdirSync) 和文件状态 (fs.statSync) 的同步版本:

function getNewestFile(dir, regexp) {
    newest = null
    files = fs.readdirSync(dir)
    one_matched = 0

    for (i = 0; i < files.length; i++) {

        if (regexp.test(files[i]) == false)
            continue
        else if (one_matched == 0) {
            newest = files[i]
            one_matched = 1
            continue
        }

        f1_time = fs.statSync(files[i]).mtime.getTime()
        f2_time = fs.statSync(newest).mtime.getTime()
        if (f1_time > f2_time)
            newest[i] = files[i]  
    }

    if (newest != null)
        return (dir + newest)
    return null
}

您可以按如下方式调用此函数:

var f = getNewestFile("./", new RegExp('.*\.mp3'))
于 2015-10-05T13:30:07.620 回答