Перечисление файлов в каталоге в Clojure - PullRequest
57 голосов
/ 19 декабря 2011

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

Ответы [ 6 ]

95 голосов
/ 19 декабря 2011

Используйте функцию file-seq.

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

(def directory (clojure.java.io/file "/path/to/directory"))
(def files (file-seq directory))
(take 10 files)
30 голосов
/ 20 декабря 2011

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

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

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

Метод экземпляра .listFiles возвращает массив (который можно использовать в качестве последовательности) объектов 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, которая возвращает предварительный обход (как последовательность), хотяфайловая иерархия, начинающаяся с данного файла.

14 голосов
/ 20 декабря 2011

Также ознакомьтесь с библиотекой fs .

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

  • Создание структур каталогов
  • Копирование, удаление, перемещение
  • Проверка и изменение разрешений
  • Разделение и нормализация путей
  • Создание временных файлов и каталогов
  • Globbing
  • Работа с файлами zip и tar
9 голосов
/ 19 декабря 2011
(use 'clojure.java.io)
(-> "/tmp" file .listFiles)

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

(.listFiles (file "/tmp"))
8 голосов
/ 22 сентября 2015

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

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

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

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

(map #(.getPath %)
     (file-seq (clojure.java.io/file ".")))
6 голосов
/ 02 апреля 2012

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

(def directory (clojure.java.io/file "/path/to/directory"))
(def files 
    (for [file (file-seq directory)] (.getName file)))
(take 10 files)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...