(defmacro with-tempfile [[file [prefix suffix & [directory]]] & body]
`(let [~file ~(if directory
`(java.io.File/createTempFile ~prefix ~suffix ~directory)
`(java.io.File/createTempFile ~prefix ~suffix))]
(try
~@body
(finally
#_(.deleteOnExit ~file)
(.delete ~file)))))
;;; EXAMPLE
;;;
(with-tempfile [f ["foo" ".txt"]]
(.getPath f))
;; => "/tmp/foo8073199252617011512.txt"
;;; NOTE
;;; http://stackoverflow.com/a/516060/3585790
;;; JVM とか スレッドが try-catch-finally の途中で終了したら
;;; 実行されない場合があって、あまりよくないという話
;;;
;;; https://www.jpcert.or.jp/java-rules/fio03-j.html
;;; .delete の代りに .deleteOnExit を使えば、
;;; スレッドの終了に対しては効果があると思う
;;; でも Error が起るとダメ
;;; nio の DELETE_ON_CLOSE を推奨している
;;;
;;; http://docs.oracle.com/javase/jp/7/api/java/nio/file/Files.html
;;; nio の DELETE_ON_CLOSE 使っても ベストエフォート とはある
;;; それが限界だろうけど
;;; 基本的には close とか不要になったタイミングで消すのがいい
;;; 使わなくなったリソースは即解放すべき
;;;
;;; 一番重要なのは、 /tmp とかじゃなくて
;;; 見れる人が制限されたディレクトリに置くという事
;;; という事でこんな感じ
(require '[clojure.java.io :as io])
(with-tempfile [f ["foo" ".txt" (io/file "path/to/secure-directory")]]
(.getPath f))
;;; どっちにしろ、ファイルが消えるかは、確実じゃないので
;;; 再起動時とか、定期的なタイミングで
;;; path/to/secure-directory を一掃した方がいいと思う