Search code examples
clojuretry-with-resources

Try-with-resources in Clojure


Does Clojure have an equivalent of Java's try-with-resources construct?

If not, what is the normal way to handle this idiom in Clojure code?

The pre-Java-7 idiom for safely opening and closing resources is verbose enough that they actually added support for try-with-resources to the language. It seems strange to me that I can't find a macro for this use case in the standard Clojure library.

An example to a mainstream Clojure-based project repository—showing how this issue is handled in practice—would be very helpful.


Solution

  • You can use with-open to bind a resource to a symbol and make sure the resource is closed once the control flow left the block.

    The following example is from clojuredocs:

    (with-open [r (clojure.java.io/input-stream "myfile.txt")] 
      (loop [c (.read r)] 
        (when (not= c -1)
          (print (char c)) 
          (recur (.read r)))))
    

    It will be expanded to the following:

    (let [r (clojure.java.io/input-stream "myfile.txt")] 
      (try
        (loop [c (.read r)] 
          (when (not= c -1)
            (print (char c)) 
            (recur (.read r))))
        (finally (.close r))))
    

    As you can see, a let block is created with a try and finally to the call .close() method.