Make directory path: Difference between revisions
(Adds Clojure solution) |
(modify Clojure example to return true if directory already exists) |
||
Line 13: | Line 13: | ||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
<lang clojure>( |
<lang clojure>(defn mkdirp [path] |
||
(let [dir (java.io.File. path)] |
|||
(if (.exists dir) |
|||
true |
|||
(.mkdirs dir))))</lang> |
|||
=={{header|Go}}== |
=={{header|Go}}== |
Revision as of 22:09, 12 August 2014
You are encouraged to solve this task according to the task description, using any language you may know.
Create a directory and any missing parents.
This task is named after the posix mkdir -p
command, and several libraries which implement the same behavior.
Please implement a function of a single path string (for example ./path/to/dir
) which has the above side-effect.
If the directory already exists, return successfully.
Ideally implementations will work equally well cross-platform (on windows, linux, and OS X).
It's likely that your language implements such a function as part of its standard library. If so, please also show how such a function would be implemented.
Clojure
<lang clojure>(defn mkdirp [path]
(let [dir (java.io.File. path)] (if (.exists dir) true (.mkdirs dir))))</lang>
Go
The standard packages include os.MkdirAll which does exactly this (and its source is also available via that link). <lang go> os.MkdirAll("/tmp/some/path/to/dir", 0770)</lang>
JavaScript
Simplified version of the popular mkdirp library:
<lang Javascript>var path = require('path'); var fs = require('fs');
function mkdirp (p, cb) {
cb = cb || function () {}; p = path.resolve(p);
fs.mkdir(p, function (er) { if (!er) { return cb(null); } switch (er.code) { case 'ENOENT': // The directory doesn't exist. Make its parent and try again. mkdirp(path.dirname(p), function (er) { if (er) cb(er); else mkdirp(p, cb); }); break;
// In the case of any other error, something is borked. default: cb(er); break; } });
}</lang>
Perl 6
There is a builtin function with the same name and it creates subdirectories by default.
<lang perl6>mkdir 'path/to/dir'</lang>
Python
<lang Python> from errno import EEXIST from os import mkdir, curdir from os.path import split, exists
def mkdirp(path, mode=0777):
head, tail = split(path) if not tail: head, tail = split(head) if head and tail and not exists(head): try: mkdirp(head, mode) except OSError as e: # be happy if someone already created the path if e.errno != EEXIST: raise if tail == curdir: # xxx/newdir/. exists if xxx/newdir exists return try: mkdir(path, mode) except OSError as e: # be happy if someone already created the path if e.errno != EEXIST: raise
</lang>
Above is a modified version of the standard library's os.makedirs
, for pedagogical purposes. In practice, you would be more likely to use the standard library call:
<lang Python> def mkdirp(path):
try: os.makedirs(path) except OSError as exc: # Python >2.5 if exc.errno == errno.EEXIST and os.path.isdir(path): pass else: raise
</lang>
In Python3 this becomes even simpler:
<lang Python> def mkdirp(path):
os.makedirs(path, exist_ok=True)
</lang>
Racket
Uses make-directory*
(NB the star — that causes the intermediate directories to be produced).
Canonical documentation at Racket Documentation for Filesystem
Creates directory specified by path, creating intermediate
directories as necessary, and never failing if path exists already.
<lang racket>#lang racket (define path-str "/tmp/woo/yay") (define path/..-str "/tmp/woo")
- clean up from a previous run
(when (directory-exists? path-str)
(delete-directory path-str) (delete-directory path/..-str))
- delete-directory/files could also be used -- but that requires goggles and rubber
- gloves to handle safely!
(define (report-path-exists)
(printf "~s exists (as a directory?):~a~%~s exists (as a directory?):~a~%~%" path/..-str (directory-exists? path/..-str) path-str (directory-exists? path-str)))
(report-path-exists)
- Really ... this is the only bit that matters!
(make-directory* path-str)
(report-path-exists)</lang>
- Output:
"/tmp/woo" exists (as a directory?):#f "/tmp/woo/yay" exists (as a directory?):#f "/tmp/woo" exists (as a directory?):#t "/tmp/woo/yay" exists (as a directory?):#t
Ruby
<lang ruby>require 'fileutils' FileUtils.mkdir_p("path/to/dir") </lang> mkdir_p also takes an array of pathnames instead of a single pathname as an argument.
REXX
The following works with any modern (Microsoft) Windows ® and/or DOS.
Operating system note: all versions of Microsoft ® DOS require the use of a blackslash [\] instead of a forward slash [/].
Usage note: without the error messages being suppressed, the MKDIR command will issue an error message if the subdirectory (or its path) already exists.
<lang rexx>/*REXX program creates a directory and all its parent paths as necessary*/
trace off /*suppress possible warning msgs.*/
dPath = 'path\to\dir'
'MKDIR' dPath "2>nul" /*alias could be used: MD Dpath */
/*stick a fork in it, we're done.*/</lang>
UNIX Shell
<lang bash>function mkdirp() { mkdir -p "$1"; }</lang>
zkl
This is for Unix as zkl doesn't have a built in mkdir method. <lang zkl>System.cmd("mkdir -p ../foo/bar")</lang> The system error code is returned (0 in this case). <lang zkl>fcn mkdir(path) { System.cmd("mkdir -p "+path) }</lang>
- Output:
zkl: mkdir("../foo/bar") 0 zkl: mkdir("/foo/bar") mkdir: cannot create directory ‘/foo’: Permission denied 256