2009-08-17 4 views
6

Clojureに書きたいダミーのJavaプログラムがあります。それはSerializableを実装するクラスとそれを保存する関数を持っています。私はClojureにこのようなプログラムを書かなかったので、この問題にアプローチする正しい方法、Clojureのデータ構造、およびAPIコールを使用する方法を知りたいと思っていましたか?ClojureでこのJavaオブジェクトをシリアル化する正しい方法は何ですか?

import java. io. *; 

public class Box implements Serializable 
{ 
private int width; private int height; 
public void setWidth(int w) 
    { width =w;} 
public void setHeight(int h) 
    {height = h;} 
} 

public static void main (String[] args) 
{ 
    Box myBox =new Box(); 
    myBox.setWidth(50); 
    myBox.setHeight(20) ; 

try { 
    FileoutputStream fs = new File("foo.ser"); 
    ObjectOUtputStream os = new ObjectOutputStream(fs); 
    os.writeObject(myBox); 
    os . close() ; 

}キャッチ(例外例){}}

答えて

9

あなたは純粋なClojureの中でそれをしたい場合は、Clojureのリーダーを使用しています。

(use 'clojure.contrib.duck-streams) 

(defn serialize [o filename] 
    (binding [*print-dup* true] 
    (with-out-writer filename 
    (prn o)))) 

(defn deserialize [filename] 
    (read-string (slurp* filename)))

例:

user> (def box {:height 50 :width 20}) 
#'user/box 
user> (serialize box "foo.ser") 
nil 
user> (deserialize "foo.ser") 
{:height 50, :width 20} 

これは、すでにほとんどのClojureのオブジェクトに対して動作しますが、ほとんどのJavaオブジェクトのために失敗しました。

user> (serialize (java.util.Date.) "date.ser") 
; Evaluation aborted. 
No method in multimethod 'print-dup' for dispatch value: class java.util.Date 

しかし、あなたはClojureのは、読み出し可能、他のオブジェクトを印刷できるようにするためにprint-dup multimethodにメソッドを追加することができます。

user> (defmethod clojure.core/print-dup java.util.Date [o w] 
     (.write w (str "#=(java.util.Date. " (.getTime o) ")"))) 
#<MultiFn clojure.lang.MultiF[email protected]> 
user> (serialize (java.util.Date.) "date.ser") 
nil 
user> (deserialize "date.ser") 
#<Date Mon Aug 17 11:30:00 PDT 2009> 

ネイティブのJavaシリアル化メソッドを持つJavaオブジェクトを使用している場合は、それを使用して独自のコードを記述する必要はありません。

関連する問題