2010. 1. 20.

JNpDp 4장

기본적인 파일 입출력을 하는 부분이다.

필요할 때가 있을듯하여 unless 매트로를 구성했다.

;; File Read/Write

(defmacro unless [expr form] (list 'if expr nil form))
파일을 열고 닫을 때를 대비해서 파일 기술자(file description)을 얻어본다. 원래는 read, write에 대해서 서로 다른 인스탄스를 리턴해야하지만 일단은 귀차니즘으로 한번에..

(defn file_open [s]
  (java.io.FileInputStream. s))

(defn file_wopen [s]
  (java.io.FileOutputStream. s))

(defn file_close [fd]
  (.close fd))
꽤나 사람 열받게 했던 부분.. reader를 구성해야하는데 일단 reader는 lambda 함수로 구성했다.
해당하는 fd에서 바이트를 읽어오는 형식으로 tail - recursion으로 구현

(defn file_input [fd]
  (let [reader (fn []
                 (try (.read fd)
                      (catch Exception e -1)))]
    (loop [data (reader)]
      (unless (== data -1)
              (do
                (print (str data))
                (recur (reader)))))))
읽은 놈을 다른 파일로 쓰기위한 부분.. 일단 reader를 만들고 이후에는 해당 기술자로 뿌렸다.
원칙대로라면 fd1, fd2도 인자로 계속 돌려줘야하는데.. 귀차니즘으로 포기..
(defn file_output [fd1 fd2]
  (let [reader (fn []
                 (try (.read fd1)
                      (catch Exception e -1)))]
    (loop [src (reader)]
      (unless (== src -1)
              (do
                (.write fd2 src)
                (recur (reader)))))))
이건 실행용 구문.. 별 의미는 없다. do를 써서 복수문장을 돌린 것이 좀 다른 거..
    
(defn file_run [s]
  (let [fd (file_open s)]
    (do
      (file_input fd)
      (file_close fd))))

(defn file_run2 [s1 s2]
  (let [fd1 (file_open s1)
        fd2 (file_wopen s2)]
    (do
      (file_output fd1  fd2)
      (file_close fd2)
      (file_close fd1))))
리더 테스트.. java에서도 스트림을 reader로 묶는데 꽤 애를 먹었는데 여기서도 역시나.. 일단 스트림을 스트림 리더로 묶고.. 다음에 특화된 리더로 다시 묶었다.

;; Reader Test
(defn reader_test []
  (let [bufReader (java.io.BufferedReader.
                   (java.io.InputStreamReader.
                    System/in))]
    (do   (do
      (print "Please Enter Your name :")
      (println "Please to meet you" (.readLine bufReader)))))

      (print "Please Enter Your name :")
      (println "Please to meet you" (.readLine bufReader)))))
swank버그로 인해서 slime내에서는 정상적인 동작이 불가능.. 외부에서 그냥 실행시키면 잘 돈다.









댓글 없음:

댓글 쓰기