ryoakg
2/15/2017 - 3:23 AM

with-tempfile.clj

(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 を一掃した方がいいと思う