2013-03-29 15 views
9

Próbuję znaleźć ostatnio utworzony plik w katalogu przy użyciu Node.js i nie można znaleźć rozwiązania. Poniższy kod wydawał się być sztuczką na jednym komputerze, ale na drugim był to tylko losowy plik z katalogu - jak się spodziewałem. Zasadniczo muszę znaleźć najnowszy plik i TYLKO ten plik.Pobierz najnowszy plik w katalogu, 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'); 

Wielkie dzięki!

+0

'ls -Srt' następnie' .pop() ' – chovy

Odpowiedz

1

Niestety, nie sądzę, że pliki są zagwarantowane w określonej kolejności.

Zamiast tego należy wywołać fs.stat (lub fs.statSync) na każdym pliku, aby uzyskać datę ostatniej modyfikacji, a następnie wybrać najnowszą po wszystkich datach.

4

to powinno załatwić sprawę ("dir" jest katalog użyć fs.readdir nad uzyskać "pliki" array):

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); 
     } 
    }); 
} 
15

Zakładając dostępność underscore (http://underscorejs.org/) oraz biorąc synchroniczne podejście (który nie wykorzystać node.js mocne strony, ale jest łatwiejsze do uchwycenia):

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; 
    }); 
} 
+0

może być z powodu aktualizacji, ale jest to _.maxBy teraz max obsługuje tylko tablicę jako jedyny arg .. – Can

+0

Próbowałem sprawdzić i znaleźć tylko 1' max' zdefiniowane przez podkreślenie - http://underscorejs.org/#max –

+0

uh moje złe, wymieszałem podkreślenie i lodash (https://lodash.com/docs/4.17.4#maxBy) – Can

1

z zsynchronizowanym wersji katalogowej odczytać (fs.readdirSync) i statusu pliku (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 
} 

można nazwać tę funkcję w następujący sposób:

var f = getNewestFile("./", new RegExp('.*\.mp3')) 
+0

Działa. Możesz pozbyć się 'one_matched' używając' if (latest == null) {'zamiast' if (one_matched == 0) {'. –

+0

najnowsze = pliki [i] zamiast najnowszych [i] = pliki [i] !! Działa świetnie .. dzięki. – Tony

+0

f1_time = fs.statSync (dir + pliki [i]) .mtime.getTime() – Tony

1

[Odpowiedź Rozszerzenie możliwości Umair do skorygowania błąd z bieżącego katalogu roboczego]

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 
} 
+0

i jest również globalny. – Derrick

+0

naprawiono, dzięki –

2

Choć nie jest to najbardziej efektywne podejście, powinno to być koncepcyjnie prosto:

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 : ""; 
} 

BTW, nie ma ob w pierwotnym poście, aby użyć listy plików synchronicznych.