ruby_object
ruby_object

Reputation: 1266

Clojure file-system portability

I want to write a simple program for playing sound clips. I want to deploy it on Windows, Linux and MacOSX. The thing that still puzzles me is location of configuration file and folder with sound clips on different operating systems. I am a Clojure noob. I am aware that Common Lisp has special file-system portability library called CL-FAD. How it is being done in Closure? How can I write portable Clojure program with different file system conventions on different systems?

Upvotes: 9

Views: 4792

Answers (3)

nrako
nrako

Reputation: 3011

For a platform-independent approach, you can find the canonical path from a path relative to the project and then join it with the filename.

(:require [clojure.java.io :as io :refer [file]]))

(defn file-dir 
  "Returns canonical path of a given path"
  [path] 
  (.getCanonicalPath (io/file path))) 

(-> "./resources" ;; relative
  (file-dir)
  (io/file "filename.txt")) ;;=> /path/to/project/resources/filename.txt

Upvotes: 0

Max Noel
Max Noel

Reputation: 8910

Note that Windows perfectly supports the forward slash as a path separator (which is awesome because that way you don't have to escape backslashes all the time).

The only significant difficulty you'll run into is that the "standard" locations (home folder, etc.) are different on Windows and UNIX systems. So you need to get those from the system properties (see the getProperty method in http://docs.oracle.com/javase/7/docs/api/java/lang/System.html).

Upvotes: 2

jbm
jbm

Reputation: 2600

You can use clojure.java.io/file to build paths in a (mostly) platform-neutral way, similarly to how you would with os.path.join in Python or File.join in Ruby.

(require '[clojure.java.io :as io])

;; On Linux
(def home "/home/jbm")
(io/file home "media" "music") ;=> #<File /home/jbm/media/music>

;; On Windows
(def home "c:\\home\\jbm")
(io/file home "media" "music") ;=> #<File c:\home\jbm\media\music>

clojure.java.io/file returns a java.io.File. If you need to get back to a string you can always use .getPath:

(-> home
  (io/file "media" "music")
  (.getPath))
;=> /home/jbm/media/music"

Is that the sort of thing you had in mind?

In addition to clojure.java.io (and, of course, the methods on java.io.File), raynes.fs is a popular file system utility library.

Upvotes: 29

Related Questions