En esta lección necesitamos crear un programa que imprima una lista de archivos en un directorio, filtrados por extensión. Al igual que en las lecciones anteriores, obtener una lista filtrada de archivos en un directorio es una utilidad integrada en la interfaz de la línea de comandos.

Leccion-5 learnyounode Lección 5 - LS filtrado

ls *.txt

En este caso, la extensión de archivo suministrada por learnyounode no incluirá el prefijo ‘.’, lo que significa que tendremos que tenerlo en cuenta en nuestro código. Además, debemos obtener nuestra lista filtrada usando entrada/salida asíncrona.

En las lecciones anteriores aprendimos a usar el módulo de sistema de archivos en nuestro código. Tendremos que hacerlo de nuevo. Sin embargo, el módulo de sistema de archivos no incluye un método incorporado para obtener extensiones de archivo (que yo sepa). Podríamos hacer alguna manipulación de cadenas para obtener la ruta de los nombres de archivo usando el módulo de sistema de archivos pasando el nombre de archivo completo a un par de métodos incorporados de JavaScript.

filename = ‘myFile.txt’
extension = filename.split(‘.’).pop();
console.log(extension)

Esto funcionará, pero por suerte para nosotros no tenemos que perder el tiempo intentando encontrar un método inteligente para derivar extensiones de nombres de archivo porque ya hay un módulo de nodos que lo hace por nosotros. Este módulo se conoce como el módulo de ruta.

var path = require(‘path’)
console.log(path.extname(‘myFile.txt’))

Eso fue fácil, y no tenemos que preocuparnos por empaquetar esto en una función para que pueda ser reutilizado. Ya se ha hecho el trabajo duro.

Solución oficial

var fs = require(‘fs’)
var path = require(‘path’)
 
var folder = process.argv[2]
var ext = ‘.’ + process.argv[3]
 
fs.readdir(folder, function (err, files) {
  if (err) return console.error(err)
  files.forEach(function(file) {
      if (path.extname(file) === ext) {
          console.log(file)
      }
  })
})

La solución oficial es pasar el módulo de sistema de archivos a la variable fs, y el módulo de ruta a ruta. También pasa el tercer y cuarto índice de la propiedad argv del objeto de proceso. Después de esto, el programa llama al método readdir() desde el módulo fs, el cual acepta una carpeta y una función callback como argumentos. La función callback acepta un error y los archivos como argumentos.

Cuando se ejecuta la función de devolución de llamada, comprobamos si hay un error y regresamos e imprimimos un mensaje de error si se produce un error. Al mismo tiempo, llamamos al método forEach() en los archivos. El método files.forEach() acepta una función de devolución de llamada como argumento.

La función de devolución de llamada acepta un archivo como argumento. El archivo se pasa a esta función desde el método files.forEach(), que recibe archivos desde el método fs.readdir(). Si la ruta del archivo es igual a la variable ext (parocess.argv[3]), el archivo se registra en la consola.

Otra solución

Mientras trabaja en este desafío, puede que se pregunte cómo puede hacer que su solución sea más reutilizable. La función en el código de abajo puede ser reutilizada para diferentes propósitos. La siguiente lección nos muestra cómo tomar este código y hacerlo modular para que pueda ser pasado a una variable como el sistema de archivos o el módulo de ruta.

var fs = require(‘fs’)
var path = require(‘path’)
 
var dir = process.argv[2]
var filterStr = process.argv[3]
 
function getFiles(dir, filterStr, callback) {
 
  fs.readdir(dir, function (err, list) {
    if (err)
      return callback(err)
 
    list = list.filter(function (file) {
      return path.extname(file) === ‘.’ + filterStr
    })
 
    callback(null, list)
  })
}
 
getFiles(dir, filterStr, function (err, list) {
  if (err)
    return console.error(‘There was an error:’, err)
 
  list.forEach(function (file) {
    console.log(file)
  })
})

En la solución anterior, el módulo de sistema de archivos se pasa a la variable fs, y el módulo de ruta a la ruta. A continuación, el tercer y cuarto índice de la propiedad argv del objeto de proceso se asignan a variables, al igual que la solución oficial.

En lugar de llamar al método fs.readdir() directamente, se declara una función llamada getFiles() con el método fs.readdir() dentro de ella.

La función getFiles() acepta un directorio (dir), una cadena de filtro (filterStr) y una función de devolución de llamada como argumentos. Dentro de getFiles(), el método fs.readdir() se llama con la variable ‘dir’ y una llamada de retorno como argumentos.

La devolución de llamada acepta error (err), y lista como argumentos. Una manera de pensar en esto es que el método fs.readdir) llamará a la función de devolución de llamada cuando esté hecho y le dará una lista.

Dentro de la llamada de retorno se utiliza el método filter() para pasar el valor de list.filter() a la variable list.

El método filter() acepta una función callback como argumento. La devolución de llamada acepta el archivo como argumento. Dentro de la función callback, el archivo se devuelve a la variable de lista comprobando si la extensión del archivo es igual a filterStr con el método path.extname().

Además, dentro de la llamada de retorno a la que se pasa fs.readdir(), la llamada de retorno se llama y se pasa ‘null’ y la variable ‘list’. Esto es lo que pasa el contenido de la lista cuando se llama getFiles.

Después de que se declara la función getFiles(), se le llama y se le pasan los argumentos ‘dir’, ‘filterStr’, y una llamada de retorno. La función callback acepta ‘err’ y ‘list’ como argumentos.

En el interior de la llamada de retorno se comprueban los errores y se devuelven si la declaración se evalúa como verdadera. El método forEach() se utiliza para recorrer la lista y pasar una función de devolución de llamada al método forEach().

Dentro de la llamada de retorno se pasa un archivo de nuestra variable de lista como argumento y luego el contenido de la variable de archivo, que tiene nuestro nombre de archivo, se imprime en la consola con el método console.log().

En la siguiente lección, Make it Modular, verá cómo esta solución puede modularizarse aún más pasándola a la propiedad de exportación del objeto del módulo.

Reader Interactions

Deja un comentario

Tu dirección de correo electrónico no será publicada.

Share This