Как создать список из всех файлов в определенном каталоге в Clojure? Должен ли я прибегать к вызову Java или может Clojure обрабатывать это изначально?
Список файлов в каталоге в Clojure
Ответ 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 ".")))