clojure 1.3에서 파일을 읽고 쓰는 “추천 된”방법을 알고 싶습니다.
- 전체 파일을 읽는 방법
- 파일을 한 줄씩 읽는 방법
- 새 파일을 작성하는 방법
- 기존 파일에 줄을 추가하는 방법
답변
우리가 여기서 이진 파일이 아닌 텍스트 파일 만하고 있다고 가정합니다.
1 번 : 전체 파일을 메모리로 읽는 방법
(slurp "/tmp/test.txt")
정말 큰 파일 일 때는 권장하지 않습니다.
번호 2 : 파일을 한 줄씩 읽는 방법
(use 'clojure.java.io)
(with-open [rdr (reader "/tmp/test.txt")]
(doseq [line (line-seq rdr)]
(println line)))
with-open
매크로 리더 본체의 단부에서 폐쇄되어 처리한다. reader 함수는 문자열 (URL 등도 가능)을로 강제 변환합니다 BufferedReader
. line-seq
게으른 시퀀스를 제공합니다. 게으른 seq의 다음 요소를 요구하면 판독기에서 행을 읽습니다.
Clojure 1.7부터는 텍스트 파일을 읽는 데 변환기 를 사용할 수도 있습니다 .
3 번 : 새 파일에 쓰는 법.
(use 'clojure.java.io)
(with-open [wrtr (writer "/tmp/test.txt")]
(.write wrtr "Line to be written"))
다시, 신체의 끝에 폐쇄되어 with-open
있는지 확인하십시오 BufferedWriter
. Writer는 BufferedWriter
java interop을 통해 사용 하는 문자열을로 강제 변환합니다 .(.write wrtr "something").
spit
의 반대 도 사용할 수 있습니다 slurp
.
(spit "/tmp/test.txt" "Line to be written")
4 번 : 기존 파일에 줄을 추가합니다.
(use 'clojure.java.io)
(with-open [wrtr (writer "/tmp/test.txt" :append true)]
(.write wrtr "Line to be appended"))
위와 동일하지만 추가 옵션이 추가되었습니다.
또는 다시 spit
반대의 경우 slurp
:
(spit "/tmp/test.txt" "Line to be written" :append true)
추신 : 다른 것을 읽지 않고 파일을 읽고 쓰는 사실에 대해 더 명확하게 설명하기 위해 먼저 File 객체를 만든 다음 BufferedReader
또는 Writer 로 강제 변환 할 수 있습니다 .
(reader (file "/tmp/test.txt"))
;; or
(writer (file "tmp/test.txt"))
파일 함수는 clojure.java.io에도 있습니다.
PS2 : 때로는 현재 디렉토리 ( “.”)가 무엇인지 쉽게 볼 수 있습니다. 두 가지 방법으로 절대 경로를 얻을 수 있습니다.
(System/getProperty "user.dir")
또는
(-> (java.io.File. ".") .getAbsolutePath)
답변
파일이 메모리에 맞는 경우 slurp 및 spit으로 파일을 읽고 쓸 수 있습니다.
(def s (slurp "filename.txt"))
(이제 파일의 내용을 문자열로 포함합니다)
(spit "newfile.txt" s)
종료하지 않고 파일 내용을 쓰면 newfile.txt가 작성됩니다. 파일에 추가하고 싶다면 할 수 있습니다
(spit "filename.txt" s :append true)
파일을 줄 단위로 읽거나 쓰려면 Java 리더와 라이터를 사용합니다. 네임 스페이스 clojure.java.io에 래핑됩니다.
(ns file.test
(:require [clojure.java.io :as io]))
(let [wrtr (io/writer "test.txt")]
(.write wrtr "hello, world!\n")
(.close wrtr))
(let [wrtr (io/writer "test.txt" :append true)]
(.write wrtr "hello again!")
(.close wrtr))
(let [rdr (io/reader "test.txt")]
(println (.readLine rdr))
(println (.readLine rdr)))
; "hello, world!"
; "hello again!"
slurp / spit과 리더 / 라이터 예제의 차이점은 파일이 후자의 let 문에서 열린 상태로 유지되고 읽기 및 쓰기가 버퍼링되므로 파일을 반복해서 읽거나 쓸 때 더 효율적입니다.
자세한 내용은 다음과 같습니다. slurp spit
clojure.java.io
Java의 BufferedReader
Java의 작성기
답변
질문 2에 관해서는, 때로는 일류 객체로 반환되는 라인 스트림을 원합니다. 이것을 지연 시퀀스로 가져오고 EOF에서 파일을 자동으로 닫으려면이 기능을 사용했습니다.
(use 'clojure.java.io)
(defn read-lines [filename]
(let [rdr (reader filename)]
(defn read-next-line []
(if-let [line (.readLine rdr)]
(cons line (lazy-seq (read-next-line)))
(.close rdr)))
(lazy-seq (read-next-line)))
)
(defn echo-file []
(doseq [line (read-lines "myfile.txt")]
(println line)))
답변
전체 파일을 읽는 방법입니다.
파일이 자원 디렉토리에있는 경우 다음을 수행 할 수 있습니다.
(let [file-content-str (slurp (clojure.java.io/resource "public/myfile.txt")])
필요 / 사용을 기억하십시오 clojure.java.io
.
답변
(require '[clojure.java.io :as io])
(io/copy (io/file "/etc/passwd") \*out*\)
답변
파일을 한 줄씩 읽으려면 더 이상 interop을 사용하지 않아도됩니다.
(->> "data.csv"
io/resource
io/reader
line-seq
(drop 1))
이는 데이터 파일이 resources 디렉토리에 유지되고 첫 번째 행은 버릴 수있는 헤더 정보라고 가정합니다.