lispとrubyとpythonと その8 ファイルIO(common lisp)
CommonLispでのファイルIOはこんな感じ。
一般的にはwith-xxxだけど、ファイル開きっぱなしの時とかはそうできない時もある。
(require 'cl-interpol) (cl-interpol:enable-interpol-syntax) ;;プリミティブなのはopen ;;まずはテキストファイル書き込み ;;:if-exists :supersedeにしているから既存のファイルがあったら作り直す ;;既存のファイルに追加するなら:appendとか ;;http://www.lispworks.com/documentation/HyperSpec/Body/f_open.htm#open (let ((ofs (open "./test.txt" :direction :output :if-exists :append :if-does-not-exist :create))) (unwind-protect (format ofs #?"hello world\n") (close ofs))) ;;読み込み ;;read-lineで一行読み込み (let ((ifs (open "./test.txt" :direction :input))) (unwind-protect (do ((l (read-line ifs nil 'EOF) (read-line ifs nil 'EOF))) ((eql l 'EOF)) (format t "~A~%" l)) (close ifs))) ;;->hello world ;;バイナリファイル書き込み (let ((ofs (open "./test.dat" :direction :output :if-exists :append :element-type 'unsigned-byte :if-does-not-exist :create))) (unwind-protect (progn (write-byte 0 ofs) (write-byte 1 ofs) (write-byte 2 ofs)) (close ofs))) ;;バイナリ読み込み (let ((ifs (open "./test.dat" :direction :input :element-type 'unsigned-byte))) (unwind-protect (progn (do ((b (read-byte ifs nil 'EOF) (read-byte ifs nil 'EOF))) ((eql b 'EOF)) (format t "~A~%" b))) (close ifs))) ;;->0 ;; 1 ;; 2 ;;一般的にはこっち (with-open-file (ofs "./test2.txt" :direction :output :if-exists :append :if-does-not-exist :create) (format ofs #?"hello world2\n")) (with-open-file (ifs "./test2.txt" :direction :input) (do ((l (read-line ifs nil 'EOF) (read-line ifs nil 'EOF))) ((eql l 'EOF)) (format t "~A~%" l))) ;;->hello world2 (with-open-file (ofs "./test2.dat" :direction :output :if-exists :append :if-does-not-exist :create :element-type 'unsigned-byte) (write-byte 0 ofs) (write-byte 1 ofs) (write-byte 2 ofs)) (with-open-file (ifs "./test2.dat" :direction :input :element-type 'unsigned-byte) (do ((b (read-byte ifs nil 'EOF) (read-byte ifs nil 'EOF))) ((eql b 'EOF)) (format t "~A~%" b))) ;;->0 ;; 1 ;; 2 ;;バッファするならこんな感じ (with-open-file (ifs "./test2.dat" :direction :input :element-type 'unsigned-byte) (let ((buf (make-array 16 :initial-element nil))) (do ((pos (read-sequence buf ifs) (read-sequence buf ifs))) ((= pos 0)) (format t "~A~%" buf)))) ;;->#(0 1 2 NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL) ;;番外編だけどseriesで読む手もある (require 'series) (series:iterate ((l (series:scan-file "./test2.txt" #'read-line))) (format t "series ~A~%" l)) ;;->series hello world2