Listado de archivos en un directorio en Clojure

5 minutos de lectura

¿Cómo puedo crear una lista de todos los archivos en un directorio específico en Clojure? ¿Tengo que recurrir a llamar a Java o Clojure puede manejar esto de forma nativa?

avatar de usuario
amigo

Usar file-seq función.

Ejemplo de uso:

(def directory (clojure.java.io/file "/path/to/directory"))
(def files (file-seq directory))
(take 10 files)

  • ¿Tienes un ejemplo de código en algún lugar? Tengo muchos problemas para encontrar uno, y el documento API al que se vinculó no es muy explicativo. Clojure novato aquí.

    –Mike Crittenden

    19 de diciembre de 2011 a las 20:11

  • file-seq es en sí mismo un buen ejemplo de código de tree-seq que es útil para acceder a cualquier estructura de datos jerárquica.

    – Alex Stodard

    20 de diciembre de 2011 a las 14:31

  • Asegúrese de ver el documentos en java.io.file objetos que devuelve file-seq.

    – Brad Koch

    15 de enero de 2016 a las 4:19


  • Técnicamente, el OP no dijo que querían que los archivos se enumeraran de forma recursiva, que (junto con los directorios en sí) es lo que obtendrá con file-seq. Si eso no es lo que querían, .listFiles además, una verificación de directorios es la mejor opción.

    – nunca zorro

    07/01/2017 a las 22:20

Clojure fue diseñado para adoptar la plataforma Java, y esta es un área en la que Clojure no proporciona su propia API. Esto significa que probablemente tengas que sumergirte en Java, pero las clases con las que tienes que trabajar son perfectamente utilizables directamente desde Clojure.

La única clase sobre la que debe leer en los javadocs es java.io.Fileque representa un ruta de archivo.

http://docs.oracle.com/javase/6/docs/api/java/io/File.html

los .listFiles El método de instancia devuelve una matriz (que puede usar como una secuencia) de File objetos: uno para cada entrada en el directorio identificado por el File instancia. Existen otros métodos útiles para determinar si un File existe, es un directorio, etc.

Ejemplo

(ns my-file-utils
  (:import java.io.File))

(defn my-ls [d]
  (println "Files in " (.getName d))
  (doseq [f (.listFiles d)]
    (if (.isDirectory f)
      (print "d ")
      (print "- "))
    (println (.getName f))))

;; Usage: (my-ls (File. "."))

Construcción de objetos de archivo

el constructor de File a veces puede ser un poco incómodo de usar (especialmente cuando se combinan muchos segmentos de ruta de una sola vez) y en este caso Clojure proporciona una función de ayuda útil: clojure.java.io/file. Como argumentos, acepta segmentos de ruta como cadenas o archivos. Los segmentos se unen con el correcto separador de caminos de la plataforma.

http://clojuredocs.org/clojure_core/clojure.java.io/file

Nota: Clojure también proporciona la file-seq función que devuelve un recorrido de preorden (como una secuencia) a través de la jerarquía de archivos que comienza en el archivo dado.

avatar de usuario
girosm

Por lo general, cuando decimos que queremos enumerar el directorio, queremos decir que queremos obtener nombres de archivos o rutas, así que ->

La forma más sencilla de listar el directorio:

(seq (.list (clojure.java.io/file ".")))

Si desea enumerarlo recursivo, entonces:

(map #(.getPath %)
    (file-seq (clojure.java.io/file ".")))

  • primera vez que veo la mejor respuesta en la parte inferior. Además, me gusta cómo la respuesta explica lo que significa en inglés “to list directory”: devolver una lista, no un árbol de archivos.

    – xealitas

    22 de julio de 2017 a las 14:21


  • si solo quieres archivosluego se puede agregar el filtro isFile (->> “./src/dir/of/interest” clojure.java.io/file file-seq (filtro #(.isFile %)) (mapa #(.getPath %)) )

    – Shivek Khurana

    31 de marzo de 2018 a las 16:51

También echa un vistazo a la biblioteca fs.

Puede que no valga la pena incorporar la dependencia adicional si solo necesita una lista de archivos en un directorio, pero hay muchas funciones útiles allí, por ejemplo para:

  • Creación de estructuras de directorio
  • Copiar, borrar, mover
  • Comprobación y cambio de permisos.
  • Dividir y normalizar rutas
  • Creación de archivos y directorios temporales
  • englobar
  • Trabajar con archivos zip y tar

(use 'clojure.java.io)
(-> "/tmp" file .listFiles)

La última expresión es una matriz de objetos de archivo devueltos por el método listFiles, invocado en el objeto de archivo creado desde la ruta “/tmp”. Esta es una manera elegante de escribir:

(.listFiles (file "/tmp"))

avatar de usuario
larry

Para hacer que el código modificado coincida con la funcionalidad del código de muestra original, debe agregar la llamada para obtener los nombres de los archivos, como este.

(def directory (clojure.java.io/file "/path/to/directory"))
(def files 
    (for [file (file-seq directory)] (.getName file)))
(take 10 files)

avatar de usuario
usuario1667313

Una macro para encargarse de enumerar los archivos en el directorio, de forma recursiva o solo en el directorio principal. También puede buscar archivos con una extensión final específica.

    ;; lists all the files recursively inside the directory passed as d like "."
(defmacro my-rec-list
  "generate the recursive list" {:added "1.0"}
  [d str rec]
  `(->> ~d
       clojure.java.io/file
       ~(if (= rec "rec")
          `file-seq
          `(.listFiles)) 
       ~(cond 
          (= str "file")  `(filter #(.isFile %))
          (= str "dir")   `(filter #(.isDirectory %))
          :always         `(filter #(.matches (.getPathMatcher 
                          (java.nio.file.FileSystems/getDefault)
                          ~str) (.getFileName (.toPath %)))))
       (mapv #(.getAbsolutePath %))))


(defn my-rec-ls-file 
  "generate the recursive list for only files in a directory"
  [d ] 
  (my-rec-list d "file" "rec"))
(defn my-rec-ls-dir 
  "generate the recursive list for only directory"
  [d ] 
  (my-rec-list d "dir" "rec"))
(defn my-rec-ls-jpg 
  "generate the recursive list for files and directory"
  [d ] 
  (my-rec-list d "glob:*.jpg" "rec"))
(defn my-ls-file 
  "generate the recursive list for only files in a directory"
  [d ] 
  (my-rec-list d "file" "norec"))
(defn my-ls-dir 
  "generate the recursive list for only directory"
  [d ] 
  (my-rec-list d "dir" "norec"))
(defn my-ls-jpg 
  "generate the recursive list for files and directory"
  [d ] 
  (my-rec-list d "glob:*.jpg" "norec"))

Conduce a una función diferente a la que se puede llamar con el directorio para obtener la lista de archivos, el directorio o el archivo de extensión coincidente, de forma recursiva o no recursiva. El ejemplo es –

(def directory (clojure.java.io/file "/Path/to/Directory"))
(my-rec-ls-jpg directory) ;; find all jpg file recessively in directory
(my-ls-jpg directory) ;; find jpg file in current directory

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad