Saltar al contenido

Recorrer archivos en una carpeta Node.JS

Si encuentras alguna parte que no comprendes puedes dejarlo en los comentarios y haremos todo lo necesario de ayudarte lo más rápido posible.

Solución:

Respuesta anterior con devoluciones de llamada

Desea utilizar la función fs.readdir para obtener el contenido del directorio y la función fs.rename para hacer el cambio de nombre. Ambas funciones tienen versiones síncronas si necesitar para esperar a que terminen antes de ejecutar el código posteriormente.

Escribí un guión rápido que hace lo que describiste.

var fs = require('fs');
var path = require('path');
// In newer Node.js versions where process is already global this isn't necessary.
var process = require("process");

var moveFrom = "/home/mike/dev/node/sonar/moveme";
var moveTo = "/home/mike/dev/node/sonar/tome"

// Loop through all the files in the temp directory
fs.readdir(moveFrom, function (err, files) 
  if (err) 
    console.error("Could not list the directory.", err);
    process.exit(1);
  

  files.forEach(function (file, index) 
    // Make one pass and make the file complete
    var fromPath = path.join(moveFrom, file);
    var toPath = path.join(moveTo, file);

    fs.stat(fromPath, function (error, stat) 
      if (error) 
        console.error("Error stating file.", error);
        return;
      

      if (stat.isFile())
        console.log("'%s' is a file.", fromPath);
      else if (stat.isDirectory())
        console.log("'%s' is a directory.", fromPath);

      fs.rename(fromPath, toPath, function (error) 
        if (error) 
          console.error("File moving error.", error);
         else 
          console.log("Moved file '%s' to '%s'.", fromPath, toPath);
        
      );
    );
  );
);

Probado en mi máquina local.

node testme.js 
'/home/mike/dev/node/sonar/moveme/hello' is a file.
'/home/mike/dev/node/sonar/moveme/test' is a directory.
'/home/mike/dev/node/sonar/moveme/test2' is a directory.
'/home/mike/dev/node/sonar/moveme/test23' is a directory.
'/home/mike/dev/node/sonar/moveme/test234' is a directory.
Moved file '/home/mike/dev/node/sonar/moveme/hello' to '/home/mike/dev/node/sonar/tome/hello'.
Moved file '/home/mike/dev/node/sonar/moveme/test' to '/home/mike/dev/node/sonar/tome/test'.
Moved file '/home/mike/dev/node/sonar/moveme/test2' to '/home/mike/dev/node/sonar/tome/test2'.
Moved file '/home/mike/dev/node/sonar/moveme/test23' to '/home/mike/dev/node/sonar/tome/test23'.
Moved file '/home/mike/dev/node/sonar/moveme/test234' to '/home/mike/dev/node/sonar/tome/test234'.

Actualización: fs.promises funciones con async / await

Inspirado por la respuesta de ma11hew28 (que se muestra aquí), aquí hay lo mismo que el anterior pero con las funciones asíncronas en fs.promises. Como señaló ma11hew28, esto puede tener limitaciones de memoria en comparación con fs.promises.opendir agregado en v12.12.0.

Código rápido a continuación.

//jshint esversion:8
//jshint node:true
const fs = require( 'fs' );
const path = require( 'path' );

const moveFrom = "/tmp/movefrom";
const moveTo = "/tmp/moveto";

// Make an async function that gets executed immediately
(async ()=>
    // Our starting point
    try 
        // Get the files as an array
        const files = await fs.promises.readdir( moveFrom );

        // Loop them all with the new for...of
        for( const file of files ) 
            // Get the full paths
            const fromPath = path.join( moveFrom, file );
            const toPath = path.join( moveTo, file );

            // Stat the file to see if we have a file or dir
            const stat = await fs.promises.stat( fromPath );

            if( stat.isFile() )
                console.log( "'%s' is a file.", fromPath );
            else if( stat.isDirectory() )
                console.log( "'%s' is a directory.", fromPath );

            // Now move async
            await fs.promises.rename( fromPath, toPath );

            // Log because we're crazy
            console.log( "Moved '%s'->'%s'", fromPath, toPath );
         // End for...of
    
    catch( e ) 
        // Catch anything bad that happens
        console.error( "We've thrown! Whoops!", e );
    

)(); // Wrap in parenthesis and call now

fs.readdir(path[, options], callback) (que Mikey A. Leonetti usó en su respuesta) y sus variantes (fsPromises.readdir(path[, options]) y fs.readdirSync(path[, options])) cada uno lee todas las entradas de un directorio en la memoria a la vez. Eso es bueno para la mayoría de los casos, pero si el directorio tiene muchas entradas y / o si desea reducir la huella de memoria de su aplicación, puede iterar sobre las entradas del directorio una a la vez.

Asincrónicamente

Los directorios son iterables asincrónicos, por lo que podría hacer algo como esto:

const fs = require('fs')

async function ls(path) 
  const dir = await fs.promises.opendir(path)
  for await (const dirent of dir) 
    console.log(dirent.name)
  


ls('.').catch(console.error)

O podrías usar dir.read() y / o dir.read(callback) directamente.

Sincrónicamente

Los directorios no se pueden sincronizar de forma iterativa, pero podrías usar dir.readSync() directamente. Por ejemplo:

const fs = require('fs')

const dir = fs.opendirSync('.')
let dirent
while ((dirent = dir.readSync()) !== null) 
  console.log(dirent.name)

dir.closeSync()

O puede hacer que la sincronización de directorios sea iterable. Por ejemplo:

const fs = require('fs')

function makeDirectoriesSyncIterable() 
  const p = fs.Dir.prototype
  if (p.hasOwnProperty(Symbol.iterator))  return 
  const entriesSync = function* () 
    try 
      let dirent
      while ((dirent = this.readSync()) !== null)  yield dirent 
     finally  this.closeSync() 
  
  if (!p.hasOwnProperty(entriesSync))  p.entriesSync = entriesSync 
  Object.defineProperty(p, Symbol.iterator, 
    configurable: true,
    enumerable: false,
    value: entriesSync,
    writable: true
  )

makeDirectoriesSyncIterable()

Y luego, podrías hacer algo como esto:

const dir = fs.opendirSync('.')
for (const dirent of dir) 
  console.log(dirent.name)


Nota: “En procesos ocupados, utilice las versiones asincrónicas de estas llamadas. Las versiones síncronas bloquearán todo el proceso hasta que se completen, deteniendo todas las conexiones”.

Referencias:

  • Documentación de Node.js: Sistema de archivos: Class fs.Dir
  • Código fuente de Node.js: fs.Dir
  • GitHub: nodejs / node: Problemas: streaming / iterative fs.readdir # 583

Puedes confirmar nuestra investigación dejando un comentario o valorándolo te estamos agradecidos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *