web-dev-qa-db-ja.com

Clojureのディレクトリ内のファイルの一覧表示

Clojureの特定のディレクトリにあるすべてのファイルからリストを作成するにはどうすればよいですか? Javaを呼び出すことに頼らなければなりませんか、それともClojureはこれをネイティブに処理できますか?

57
Mike Crittenden

使用する - file-seq 関数。

使用例:

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

Clojureは、Javaプラットフォームを採用するように設計されています。これは、Clojureが独自のAPIを提供していない領域の1つです。つまり、Java withはClojureから直接完全に使用できます。

Javadocsで読むべきクラスはJava.io.Fileファイルパスを表します。

http://docs.Oracle.com/javase/6/docs/api/Java/io/File.html

.listFiles instanceメソッドは、Fileオブジェクトの配列(これをseqとして使用できます)を返します。これは、Fileインスタンスによって識別されるディレクトリ内のエントリごとに1つです。 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として)先行予約のウォークを返します。

30
raek

fs library も確認してください。

ディレクトリ内のファイルのリストだけが必要な場合は、追加の依存関係を取得する価値はないかもしれませんが、次のような便利なユーティリティ関数がたくさんあります。

  • ディレクトリ構造の作成
  • コピー、削除、移動
  • 権限の確認と変更
  • パスの分割と正規化
  • 一時ファイルとディレクトリの作成
  • グロビング
  • Zipファイルとtarファイルの使用
14
Christian Berg
(use 'clojure.Java.io)
(-> "/tmp" file .listFiles)

後者の式は、listFilesメソッドから返されるFileオブジェクトの配列であり、パス「/ tmp」から作成されたファイルオブジェクトで呼び出されます。これは書くための派手な方法です:

(.listFiles (file "/tmp"))
9
Michiel Borkent

通常、ディレクトリを一覧表示すると言う場合、ファイル名またはパスを取得することを意味するため、->

ディレクトリをリストする最も簡単な方法:

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

再帰的にリストしたい場合:

(map #(.getPath %)
     (file-seq (clojure.Java.io/file ".")))
8
twistsm

変更したコードを元のサンプルコードの機能と一致させるには、次のようにファイル名を取得する呼び出しを追加する必要があります。

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