Подтвердить что ты не робот

Список файлов в каталоге в Clojure

Как создать список из всех файлов в определенном каталоге в Clojure? Должен ли я прибегать к вызову Java или может Clojure обрабатывать это изначально?

4b9b3361

Ответ 1

Используйте file-seq.

Пример использования:

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

Ответ 2

Clojure был разработан, чтобы охватить платформу Java, и это одна из областей, где Clojure не предоставляет свой собственный API. Это означает, что вам, вероятно, придется погрузиться в Java, но классы, с которыми вы должны работать, отлично используются непосредственно из Clojure.

Один класс, который вы должны прочитать в javadocs, это java.io.File, который представляет путь к файлу.

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

Метод экземпляра .listFiles возвращает массив (который вы можете использовать как seq) объектов File - по одному для каждой записи в каталоге, идентифицированном экземпляром File. Существуют и другие полезные методы определения того, существует ли File, является ли каталог и т.д.

Пример

(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. "."))

Построение объектов файла

Конструктор File иногда может быть немного неудобен для использования (особенно при слиянии многих сегментов пути за один раз), и в этом случае Clojure предоставляет полезную вспомогательную функцию: clojure.java.io/file. В качестве аргументов он принимает сегменты пути как строки или файлы. Сегменты соединены с правильным разделителем пути платформы.

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

Примечание: Clojure также предоставляет функцию file-seq, которая возвращает предварительный ход (как seq), хотя иерархия файлов начинается с данного файла.

Ответ 3

Также ознакомьтесь с fs library.

Возможно, не стоит тянуть дополнительную зависимость, если вам нужен только список файлов в каталоге, но есть много полезных служебных функций, например, для:

  • Создание структур каталогов
  • Копирование, удаление, перемещение
  • Проверка и изменение разрешений
  • Разделение и нормализация путей
  • Создание временных файлов и каталогов
  • Подстановка
  • Работа с файлами zip и tar

Ответ 4

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

Последнее выражение представляет собой массив объектов File, возвращаемых из метода listFiles, вызываемый файлом-объектом, созданным с пути "/tmp". Это причудливый способ написать:

(.listFiles (file "/tmp"))

Ответ 5

Чтобы модифицированный код соответствовал функциональности исходного кода примера, вы должны добавить вызов, чтобы получить имена файлов, например.

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

Ответ 6

Обычно, когда мы говорим, что хотим перечислить каталог, мы подразумеваем, что мы хотим получить имена файлов или пути, поэтому →

Самый простой способ перечислить каталог:

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

Если вы хотите перечислить его рекурсивным, то:

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