rlm@10
|
1 ; Copyright (c) Rich Hickey. All rights reserved.
|
rlm@10
|
2 ; The use and distribution terms for this software are covered by the
|
rlm@10
|
3 ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
|
rlm@10
|
4 ; which can be found in the file epl-v10.html at the root of this distribution.
|
rlm@10
|
5 ; By using this software in any fashion, you are agreeing to be bound by
|
rlm@10
|
6 ; the terms of this license.
|
rlm@10
|
7 ; You must not remove this notice, or any other, from this software.
|
rlm@10
|
8
|
rlm@10
|
9 (ns
|
rlm@10
|
10 ^{:author "Stuart Sierra, Chas Emerick, Stuart Halloway",
|
rlm@10
|
11 :doc "This file defines polymorphic I/O utility functions for Clojure."}
|
rlm@10
|
12 clojure.java.io
|
rlm@10
|
13 (:import
|
rlm@10
|
14 (java.io Reader InputStream InputStreamReader PushbackReader
|
rlm@10
|
15 BufferedReader File OutputStream
|
rlm@10
|
16 OutputStreamWriter BufferedWriter Writer
|
rlm@10
|
17 FileInputStream FileOutputStream ByteArrayOutputStream
|
rlm@10
|
18 StringReader ByteArrayInputStream
|
rlm@10
|
19 BufferedInputStream BufferedOutputStream
|
rlm@10
|
20 CharArrayReader Closeable)
|
rlm@10
|
21 (java.net URI URL MalformedURLException Socket)))
|
rlm@10
|
22
|
rlm@10
|
23 (def
|
rlm@10
|
24 ^{:doc "Type object for a Java primitive byte array."
|
rlm@10
|
25 :private true
|
rlm@10
|
26 }
|
rlm@10
|
27 byte-array-type (class (make-array Byte/TYPE 0)))
|
rlm@10
|
28
|
rlm@10
|
29 (def
|
rlm@10
|
30 ^{:doc "Type object for a Java primitive char array."
|
rlm@10
|
31 :private true}
|
rlm@10
|
32 char-array-type (class (make-array Character/TYPE 0)))
|
rlm@10
|
33
|
rlm@10
|
34 (defprotocol ^{:added "1.2"} Coercions
|
rlm@10
|
35 "Coerce between various 'resource-namish' things."
|
rlm@10
|
36 (^{:tag java.io.File, :added "1.2"} as-file [x] "Coerce argument to a file.")
|
rlm@10
|
37 (^{:tag java.net.URL, :added "1.2"} as-url [x] "Coerce argument to a URL."))
|
rlm@10
|
38
|
rlm@10
|
39 (extend-protocol Coercions
|
rlm@10
|
40 nil
|
rlm@10
|
41 (as-file [_] nil)
|
rlm@10
|
42 (as-url [_] nil)
|
rlm@10
|
43
|
rlm@10
|
44 String
|
rlm@10
|
45 (as-file [s] (File. s))
|
rlm@10
|
46 (as-url [s] (URL. s))
|
rlm@10
|
47
|
rlm@10
|
48 File
|
rlm@10
|
49 (as-file [f] f)
|
rlm@10
|
50 (as-url [f] (.toURL f))
|
rlm@10
|
51
|
rlm@10
|
52 URL
|
rlm@10
|
53 (as-url [u] u)
|
rlm@10
|
54 (as-file [u]
|
rlm@10
|
55 (if (= "file" (.getProtocol u))
|
rlm@10
|
56 (as-file (.getPath u))
|
rlm@10
|
57 (throw (IllegalArgumentException. "Not a file: " u))))
|
rlm@10
|
58
|
rlm@10
|
59 URI
|
rlm@10
|
60 (as-url [u] (.toURL u))
|
rlm@10
|
61 (as-file [u] (as-file (as-url u))))
|
rlm@10
|
62
|
rlm@10
|
63 (defprotocol ^{:added "1.2"} IOFactory
|
rlm@10
|
64 "Factory functions that create ready-to-use, buffered versions of
|
rlm@10
|
65 the various Java I/O stream types, on top of anything that can
|
rlm@10
|
66 be unequivocally converted to the requested kind of stream.
|
rlm@10
|
67
|
rlm@10
|
68 Common options include
|
rlm@10
|
69
|
rlm@10
|
70 :append true to open stream in append mode
|
rlm@10
|
71 :encoding string name of encoding to use, e.g. \"UTF-8\".
|
rlm@10
|
72
|
rlm@10
|
73 Callers should generally prefer the higher level API provided by
|
rlm@10
|
74 reader, writer, input-stream, and output-stream."
|
rlm@10
|
75 (^{:added "1.2"} make-reader [x opts] "Creates a BufferedReader. See also IOFactory docs.")
|
rlm@10
|
76 (^{:added "1.2"} make-writer [x opts] "Creates a BufferedWriter. See also IOFactory docs.")
|
rlm@10
|
77 (^{:added "1.2"} make-input-stream [x opts] "Creates a BufferedInputStream. See also IOFactory docs.")
|
rlm@10
|
78 (^{:added "1.2"} make-output-stream [x opts] "Creates a BufferedOutputStream. See also IOFactory docs."))
|
rlm@10
|
79
|
rlm@10
|
80 (defn ^Reader reader
|
rlm@10
|
81 "Attempts to coerce its argument into an open java.io.Reader.
|
rlm@10
|
82 Default implementations always return a java.io.BufferedReader.
|
rlm@10
|
83
|
rlm@10
|
84 Default implementations are provided for Reader, BufferedReader,
|
rlm@10
|
85 InputStream, File, URI, URL, Socket, byte arrays, character arrays,
|
rlm@10
|
86 and String.
|
rlm@10
|
87
|
rlm@10
|
88 If argument is a String, it tries to resolve it first as a URI, then
|
rlm@10
|
89 as a local file name. URIs with a 'file' protocol are converted to
|
rlm@10
|
90 local file names.
|
rlm@10
|
91
|
rlm@10
|
92 Should be used inside with-open to ensure the Reader is properly
|
rlm@10
|
93 closed."
|
rlm@10
|
94 {:added "1.2"}
|
rlm@10
|
95 [x & opts]
|
rlm@10
|
96 (make-reader x (when opts (apply hash-map opts))))
|
rlm@10
|
97
|
rlm@10
|
98 (defn ^Writer writer
|
rlm@10
|
99 "Attempts to coerce its argument into an open java.io.Writer.
|
rlm@10
|
100 Default implementations always return a java.io.BufferedWriter.
|
rlm@10
|
101
|
rlm@10
|
102 Default implementations are provided for Writer, BufferedWriter,
|
rlm@10
|
103 OutputStream, File, URI, URL, Socket, and String.
|
rlm@10
|
104
|
rlm@10
|
105 If the argument is a String, it tries to resolve it first as a URI, then
|
rlm@10
|
106 as a local file name. URIs with a 'file' protocol are converted to
|
rlm@10
|
107 local file names.
|
rlm@10
|
108
|
rlm@10
|
109 Should be used inside with-open to ensure the Writer is properly
|
rlm@10
|
110 closed."
|
rlm@10
|
111 {:added "1.2"}
|
rlm@10
|
112 [x & opts]
|
rlm@10
|
113 (make-writer x (when opts (apply hash-map opts))))
|
rlm@10
|
114
|
rlm@10
|
115 (defn ^InputStream input-stream
|
rlm@10
|
116 "Attempts to coerce its argument into an open java.io.InputStream.
|
rlm@10
|
117 Default implementations always return a java.io.BufferedInputStream.
|
rlm@10
|
118
|
rlm@10
|
119 Default implementations are defined for OutputStream, File, URI, URL,
|
rlm@10
|
120 Socket, byte array, and String arguments.
|
rlm@10
|
121
|
rlm@10
|
122 If the argument is a String, it tries to resolve it first as a URI, then
|
rlm@10
|
123 as a local file name. URIs with a 'file' protocol are converted to
|
rlm@10
|
124 local file names.
|
rlm@10
|
125
|
rlm@10
|
126 Should be used inside with-open to ensure the InputStream is properly
|
rlm@10
|
127 closed."
|
rlm@10
|
128 {:added "1.2"}
|
rlm@10
|
129 [x & opts]
|
rlm@10
|
130 (make-input-stream x (when opts (apply hash-map opts))))
|
rlm@10
|
131
|
rlm@10
|
132 (defn ^OutputStream output-stream
|
rlm@10
|
133 "Attempts to coerce its argument into an open java.io.OutputStream.
|
rlm@10
|
134 Default implementations always return a java.io.BufferedOutputStream.
|
rlm@10
|
135
|
rlm@10
|
136 Default implementations are defined for OutputStream, File, URI, URL,
|
rlm@10
|
137 Socket, and String arguments.
|
rlm@10
|
138
|
rlm@10
|
139 If the argument is a String, it tries to resolve it first as a URI, then
|
rlm@10
|
140 as a local file name. URIs with a 'file' protocol are converted to
|
rlm@10
|
141 local file names.
|
rlm@10
|
142
|
rlm@10
|
143 Should be used inside with-open to ensure the OutputStream is
|
rlm@10
|
144 properly closed."
|
rlm@10
|
145 {:added "1.2"}
|
rlm@10
|
146 [x & opts]
|
rlm@10
|
147 (make-output-stream x (when opts (apply hash-map opts))))
|
rlm@10
|
148
|
rlm@10
|
149 (defn- ^Boolean append? [opts]
|
rlm@10
|
150 (boolean (:append opts)))
|
rlm@10
|
151
|
rlm@10
|
152 (defn- ^String encoding [opts]
|
rlm@10
|
153 (or (:encoding opts) "UTF-8"))
|
rlm@10
|
154
|
rlm@10
|
155 (defn- buffer-size [opts]
|
rlm@10
|
156 (or (:buffer-size opts) 1024))
|
rlm@10
|
157
|
rlm@10
|
158 (def default-streams-impl
|
rlm@10
|
159 {:make-reader (fn [x opts] (make-reader (make-input-stream x opts) opts))
|
rlm@10
|
160 :make-writer (fn [x opts] (make-writer (make-output-stream x opts) opts))
|
rlm@10
|
161 :make-input-stream (fn [x opts]
|
rlm@10
|
162 (throw (IllegalArgumentException.
|
rlm@10
|
163 (str "Cannot open <" (pr-str x) "> as an InputStream."))))
|
rlm@10
|
164 :make-output-stream (fn [x opts]
|
rlm@10
|
165 (throw (IllegalArgumentException.
|
rlm@10
|
166 (str "Cannot open <" (pr-str x) "> as an OutputStream."))))})
|
rlm@10
|
167
|
rlm@10
|
168 (defn- inputstream->reader
|
rlm@10
|
169 [^InputStream is opts]
|
rlm@10
|
170 (make-reader (InputStreamReader. is (encoding opts)) opts))
|
rlm@10
|
171
|
rlm@10
|
172 (defn- outputstream->writer
|
rlm@10
|
173 [^OutputStream os opts]
|
rlm@10
|
174 (make-writer (OutputStreamWriter. os (encoding opts)) opts))
|
rlm@10
|
175
|
rlm@10
|
176 (extend BufferedInputStream
|
rlm@10
|
177 IOFactory
|
rlm@10
|
178 (assoc default-streams-impl
|
rlm@10
|
179 :make-input-stream (fn [x opts] x)
|
rlm@10
|
180 :make-reader inputstream->reader))
|
rlm@10
|
181
|
rlm@10
|
182 (extend InputStream
|
rlm@10
|
183 IOFactory
|
rlm@10
|
184 (assoc default-streams-impl
|
rlm@10
|
185 :make-input-stream (fn [x opts] (BufferedInputStream. x))
|
rlm@10
|
186 :make-reader inputstream->reader))
|
rlm@10
|
187
|
rlm@10
|
188 (extend Reader
|
rlm@10
|
189 IOFactory
|
rlm@10
|
190 (assoc default-streams-impl
|
rlm@10
|
191 :make-reader (fn [x opts] (BufferedReader. x))))
|
rlm@10
|
192
|
rlm@10
|
193 (extend BufferedReader
|
rlm@10
|
194 IOFactory
|
rlm@10
|
195 (assoc default-streams-impl
|
rlm@10
|
196 :make-reader (fn [x opts] x)))
|
rlm@10
|
197
|
rlm@10
|
198 (extend Writer
|
rlm@10
|
199 IOFactory
|
rlm@10
|
200 (assoc default-streams-impl
|
rlm@10
|
201 :make-writer (fn [x opts] (BufferedWriter. x))))
|
rlm@10
|
202
|
rlm@10
|
203 (extend BufferedWriter
|
rlm@10
|
204 IOFactory
|
rlm@10
|
205 (assoc default-streams-impl
|
rlm@10
|
206 :make-writer (fn [x opts] x)))
|
rlm@10
|
207
|
rlm@10
|
208 (extend OutputStream
|
rlm@10
|
209 IOFactory
|
rlm@10
|
210 (assoc default-streams-impl
|
rlm@10
|
211 :make-output-stream (fn [x opts] (BufferedOutputStream. x))
|
rlm@10
|
212 :make-writer outputstream->writer))
|
rlm@10
|
213
|
rlm@10
|
214 (extend BufferedOutputStream
|
rlm@10
|
215 IOFactory
|
rlm@10
|
216 (assoc default-streams-impl
|
rlm@10
|
217 :make-output-stream (fn [x opts] x)
|
rlm@10
|
218 :make-writer outputstream->writer))
|
rlm@10
|
219
|
rlm@10
|
220 (extend File
|
rlm@10
|
221 IOFactory
|
rlm@10
|
222 (assoc default-streams-impl
|
rlm@10
|
223 :make-input-stream (fn [^File x opts] (make-input-stream (FileInputStream. x) opts))
|
rlm@10
|
224 :make-output-stream (fn [^File x opts] (make-output-stream (FileOutputStream. x (append? opts)) opts))))
|
rlm@10
|
225
|
rlm@10
|
226 (extend URL
|
rlm@10
|
227 IOFactory
|
rlm@10
|
228 (assoc default-streams-impl
|
rlm@10
|
229 :make-input-stream (fn [^URL x opts]
|
rlm@10
|
230 (make-input-stream
|
rlm@10
|
231 (if (= "file" (.getProtocol x))
|
rlm@10
|
232 (FileInputStream. (.getPath x))
|
rlm@10
|
233 (.openStream x)) opts))
|
rlm@10
|
234 :make-output-stream (fn [^URL x opts]
|
rlm@10
|
235 (if (= "file" (.getProtocol x))
|
rlm@10
|
236 (make-output-stream (File. (.getPath x)) opts)
|
rlm@10
|
237 (throw (IllegalArgumentException. (str "Can not write to non-file URL <" x ">")))))))
|
rlm@10
|
238
|
rlm@10
|
239 (extend URI
|
rlm@10
|
240 IOFactory
|
rlm@10
|
241 (assoc default-streams-impl
|
rlm@10
|
242 :make-input-stream (fn [^URI x opts] (make-input-stream (.toURL x) opts))
|
rlm@10
|
243 :make-output-stream (fn [^URI x opts] (make-output-stream (.toURL x) opts))))
|
rlm@10
|
244
|
rlm@10
|
245 (extend String
|
rlm@10
|
246 IOFactory
|
rlm@10
|
247 (assoc default-streams-impl
|
rlm@10
|
248 :make-input-stream (fn [^String x opts]
|
rlm@10
|
249 (try
|
rlm@10
|
250 (make-input-stream (URL. x) opts)
|
rlm@10
|
251 (catch MalformedURLException e
|
rlm@10
|
252 (make-input-stream (File. x) opts))))
|
rlm@10
|
253 :make-output-stream (fn [^String x opts]
|
rlm@10
|
254 (try
|
rlm@10
|
255 (make-output-stream (URL. x) opts)
|
rlm@10
|
256 (catch MalformedURLException err
|
rlm@10
|
257 (make-output-stream (File. x) opts))))))
|
rlm@10
|
258
|
rlm@10
|
259 (extend Socket
|
rlm@10
|
260 IOFactory
|
rlm@10
|
261 (assoc default-streams-impl
|
rlm@10
|
262 :make-input-stream (fn [^Socket x opts] (make-input-stream (.getInputStream x) opts))
|
rlm@10
|
263 :make-output-stream (fn [^Socket x opts] (make-output-stream (.getOutputStream x) opts))))
|
rlm@10
|
264
|
rlm@10
|
265 (extend byte-array-type
|
rlm@10
|
266 IOFactory
|
rlm@10
|
267 (assoc default-streams-impl
|
rlm@10
|
268 :make-input-stream (fn [x opts] (make-input-stream (ByteArrayInputStream. x) opts))))
|
rlm@10
|
269
|
rlm@10
|
270 (extend char-array-type
|
rlm@10
|
271 IOFactory
|
rlm@10
|
272 (assoc default-streams-impl
|
rlm@10
|
273 :make-reader (fn [x opts] (make-reader (CharArrayReader. x) opts))))
|
rlm@10
|
274
|
rlm@10
|
275 (extend Object
|
rlm@10
|
276 IOFactory
|
rlm@10
|
277 default-streams-impl)
|
rlm@10
|
278
|
rlm@10
|
279 (defmulti
|
rlm@10
|
280 #^{:doc "Internal helper for copy"
|
rlm@10
|
281 :private true
|
rlm@10
|
282 :arglists '([input output opts])}
|
rlm@10
|
283 do-copy
|
rlm@10
|
284 (fn [input output opts] [(type input) (type output)]))
|
rlm@10
|
285
|
rlm@10
|
286 (defmethod do-copy [InputStream OutputStream] [#^InputStream input #^OutputStream output opts]
|
rlm@10
|
287 (let [buffer (make-array Byte/TYPE (buffer-size opts))]
|
rlm@10
|
288 (loop []
|
rlm@10
|
289 (let [size (.read input buffer)]
|
rlm@10
|
290 (when (pos? size)
|
rlm@10
|
291 (do (.write output buffer 0 size)
|
rlm@10
|
292 (recur)))))))
|
rlm@10
|
293
|
rlm@10
|
294 (defmethod do-copy [InputStream Writer] [#^InputStream input #^Writer output opts]
|
rlm@10
|
295 (let [#^"[B" buffer (make-array Byte/TYPE (buffer-size opts))]
|
rlm@10
|
296 (loop []
|
rlm@10
|
297 (let [size (.read input buffer)]
|
rlm@10
|
298 (when (pos? size)
|
rlm@10
|
299 (let [chars (.toCharArray (String. buffer 0 size (encoding opts)))]
|
rlm@10
|
300 (do (.write output chars)
|
rlm@10
|
301 (recur))))))))
|
rlm@10
|
302
|
rlm@10
|
303 (defmethod do-copy [InputStream File] [#^InputStream input #^File output opts]
|
rlm@10
|
304 (with-open [out (FileOutputStream. output)]
|
rlm@10
|
305 (do-copy input out opts)))
|
rlm@10
|
306
|
rlm@10
|
307 (defmethod do-copy [Reader OutputStream] [#^Reader input #^OutputStream output opts]
|
rlm@10
|
308 (let [#^"[C" buffer (make-array Character/TYPE (buffer-size opts))]
|
rlm@10
|
309 (loop []
|
rlm@10
|
310 (let [size (.read input buffer)]
|
rlm@10
|
311 (when (pos? size)
|
rlm@10
|
312 (let [bytes (.getBytes (String. buffer 0 size) (encoding opts))]
|
rlm@10
|
313 (do (.write output bytes)
|
rlm@10
|
314 (recur))))))))
|
rlm@10
|
315
|
rlm@10
|
316 (defmethod do-copy [Reader Writer] [#^Reader input #^Writer output opts]
|
rlm@10
|
317 (let [#^"[C" buffer (make-array Character/TYPE (buffer-size opts))]
|
rlm@10
|
318 (loop []
|
rlm@10
|
319 (let [size (.read input buffer)]
|
rlm@10
|
320 (when (pos? size)
|
rlm@10
|
321 (do (.write output buffer 0 size)
|
rlm@10
|
322 (recur)))))))
|
rlm@10
|
323
|
rlm@10
|
324 (defmethod do-copy [Reader File] [#^Reader input #^File output opts]
|
rlm@10
|
325 (with-open [out (FileOutputStream. output)]
|
rlm@10
|
326 (do-copy input out opts)))
|
rlm@10
|
327
|
rlm@10
|
328 (defmethod do-copy [File OutputStream] [#^File input #^OutputStream output opts]
|
rlm@10
|
329 (with-open [in (FileInputStream. input)]
|
rlm@10
|
330 (do-copy in output opts)))
|
rlm@10
|
331
|
rlm@10
|
332 (defmethod do-copy [File Writer] [#^File input #^Writer output opts]
|
rlm@10
|
333 (with-open [in (FileInputStream. input)]
|
rlm@10
|
334 (do-copy in output opts)))
|
rlm@10
|
335
|
rlm@10
|
336 (defmethod do-copy [File File] [#^File input #^File output opts]
|
rlm@10
|
337 (with-open [in (FileInputStream. input)
|
rlm@10
|
338 out (FileOutputStream. output)]
|
rlm@10
|
339 (do-copy in out opts)))
|
rlm@10
|
340
|
rlm@10
|
341 (defmethod do-copy [String OutputStream] [#^String input #^OutputStream output opts]
|
rlm@10
|
342 (do-copy (StringReader. input) output opts))
|
rlm@10
|
343
|
rlm@10
|
344 (defmethod do-copy [String Writer] [#^String input #^Writer output opts]
|
rlm@10
|
345 (do-copy (StringReader. input) output opts))
|
rlm@10
|
346
|
rlm@10
|
347 (defmethod do-copy [String File] [#^String input #^File output opts]
|
rlm@10
|
348 (do-copy (StringReader. input) output opts))
|
rlm@10
|
349
|
rlm@10
|
350 (defmethod do-copy [char-array-type OutputStream] [input #^OutputStream output opts]
|
rlm@10
|
351 (do-copy (CharArrayReader. input) output opts))
|
rlm@10
|
352
|
rlm@10
|
353 (defmethod do-copy [char-array-type Writer] [input #^Writer output opts]
|
rlm@10
|
354 (do-copy (CharArrayReader. input) output opts))
|
rlm@10
|
355
|
rlm@10
|
356 (defmethod do-copy [char-array-type File] [input #^File output opts]
|
rlm@10
|
357 (do-copy (CharArrayReader. input) output opts))
|
rlm@10
|
358
|
rlm@10
|
359 (defmethod do-copy [byte-array-type OutputStream] [#^"[B" input #^OutputStream output opts]
|
rlm@10
|
360 (do-copy (ByteArrayInputStream. input) output opts))
|
rlm@10
|
361
|
rlm@10
|
362 (defmethod do-copy [byte-array-type Writer] [#^"[B" input #^Writer output opts]
|
rlm@10
|
363 (do-copy (ByteArrayInputStream. input) output opts))
|
rlm@10
|
364
|
rlm@10
|
365 (defmethod do-copy [byte-array-type File] [#^"[B" input #^Writer output opts]
|
rlm@10
|
366 (do-copy (ByteArrayInputStream. input) output opts))
|
rlm@10
|
367
|
rlm@10
|
368 (defn copy
|
rlm@10
|
369 "Copies input to output. Returns nil or throws IOException.
|
rlm@10
|
370 Input may be an InputStream, Reader, File, byte[], or String.
|
rlm@10
|
371 Output may be an OutputStream, Writer, or File.
|
rlm@10
|
372
|
rlm@10
|
373 Options are key/value pairs and may be one of
|
rlm@10
|
374
|
rlm@10
|
375 :buffer-size buffer size to use, default is 1024.
|
rlm@10
|
376 :encoding encoding to use if converting between
|
rlm@10
|
377 byte and char streams.
|
rlm@10
|
378
|
rlm@10
|
379 Does not close any streams except those it opens itself
|
rlm@10
|
380 (on a File)."
|
rlm@10
|
381 {:added "1.2"}
|
rlm@10
|
382 [input output & opts]
|
rlm@10
|
383 (do-copy input output (when opts (apply hash-map opts))))
|
rlm@10
|
384
|
rlm@10
|
385 (defn ^String as-relative-path
|
rlm@10
|
386 "Take an as-file-able thing and return a string if it is
|
rlm@10
|
387 a relative path, else IllegalArgumentException."
|
rlm@10
|
388 {:added "1.2"}
|
rlm@10
|
389 [x]
|
rlm@10
|
390 (let [^File f (as-file x)]
|
rlm@10
|
391 (if (.isAbsolute f)
|
rlm@10
|
392 (throw (IllegalArgumentException. (str f " is not a relative path")))
|
rlm@10
|
393 (.getPath f))))
|
rlm@10
|
394
|
rlm@10
|
395 (defn ^File file
|
rlm@10
|
396 "Returns a java.io.File, passing each arg to as-file. Multiple-arg
|
rlm@10
|
397 versions treat the first argument as parent and subsequent args as
|
rlm@10
|
398 children relative to the parent."
|
rlm@10
|
399 {:added "1.2"}
|
rlm@10
|
400 ([arg]
|
rlm@10
|
401 (as-file arg))
|
rlm@10
|
402 ([parent child]
|
rlm@10
|
403 (File. ^File (as-file parent) ^String (as-relative-path child)))
|
rlm@10
|
404 ([parent child & more]
|
rlm@10
|
405 (reduce file (file parent child) more)))
|
rlm@10
|
406
|
rlm@10
|
407 (defn delete-file
|
rlm@10
|
408 "Delete file f. Raise an exception if it fails unless silently is true."
|
rlm@10
|
409 {:added "1.2"}
|
rlm@10
|
410 [f & [silently]]
|
rlm@10
|
411 (or (.delete (file f))
|
rlm@10
|
412 silently
|
rlm@10
|
413 (throw (java.io.IOException. (str "Couldn't delete " f)))))
|
rlm@10
|
414
|
rlm@10
|
415 (defn make-parents
|
rlm@10
|
416 "Given the same arg(s) as for file, creates all parent directories of
|
rlm@10
|
417 the file they represent."
|
rlm@10
|
418 {:added "1.2"}
|
rlm@10
|
419 [f & more]
|
rlm@10
|
420 (.mkdirs (.getParentFile ^File (apply file f more))))
|
rlm@10
|
421
|
rlm@10
|
422 (defn ^URL resource
|
rlm@10
|
423 "Returns the URL for a named resource. Use the context class loader
|
rlm@10
|
424 if no loader is specified."
|
rlm@10
|
425 {:added "1.2"}
|
rlm@10
|
426 ([n] (resource n (.getContextClassLoader (Thread/currentThread))))
|
rlm@10
|
427 ([n ^ClassLoader loader] (.getResource loader n)))
|