Clojure 读写文件

Clojure读取文件
写文件
Clojure读取文件

简单读文件(slurp)

最简单的读取文件可以采用slurp,主要作用是读取文件并以字符串的形式返回文件内容,因为其将文件直接存入内存,此方法适用于小文件的读取。

   (slurp "test.file")

在repl里面可以直接打印出字符串内容。

Clojure IO标准库

Clojure中的文件io包装在标准库clojure.java.io包中,我们用reader进行文件读取。

(ns reader.read-file
  (:require [clojure.java.io :as io]))

(def testfile (io/file "E:/hack/clojure-cook/src/reader/snake.clj"))
(with-open [rdr (io/input-stream testfile)]
  (loop  [c (.read rdr)]
    (if (not= c -1)
      (do 
        (+ x c)
        (recur (.read rdr))))))

这段代码里用到了两个重要的函数,file和reader。file函数主要获取java.io.File对象。可以使用以下方法来获取file对象。

(ns reader.file-demo
  (:require [clojure.java.io :as io]))

(def f (io/file "E:/hack/clojure-cook/src/reader/snake.clj"))

(def data-f 
  (io/file 
   (io/resource "snake.clj)))

其中resource是从项目读取资源,需要在project.clj中配置资源的文件夹:

:resource-paths ["E:/hack/clojure-cook/src/reader"] 使用java io

除了读取本地文件,也可以读取网络信息,比如:

(ns reader.file-demo
  (:require [clojure.java.io :as io])
  (:import (java.net URL)
           (java.io InputStreamReader BufferedReader)))


(defn fetch-url[address]
  (with-open [stream (.openStream (URL. address))]
    (let [buf (BufferedReader.
               (InputStreamReader. stream))]
      (apply str (line-seq buf)))))

(fetch-url "http://www.baidu.com")
写文件

简单写文件(split)

(ns reader.file-demo
  (:require [clojure.java.io :as io]))
(def out (io/file "demo.file"))
(spit out "test file")

spit是和slurp相对应的函数,只能进行极小且简单的文件处理,如果进行复杂的文件处理还需要使用Clojure IO库,或者java IO库。

Clojure IO 写文件(split)

(ns reader.file-demo
  (:require [clojure.java.io :as io]))

(def out (io/file "demo.file"))

(defn write-file [content]
  (with-open [w (io/writer out)]
    (.write w content)))

(write-file "test file second")

来源: http://blog.brucefeng.info/post/clojure-readwrite-file#toc_5

补充

使用slurp抓取网页内容及制定编码

 (slurp "http://163.com" :encoding  "gb2312")

使用reader提高读取效率

(require '[clojure.java.io :as io])
(with-open [r (io/reader "file.txt")]
  (doseq [liene (line-seq r)]
    (println line)))  

使用with-open对多文件操作

(with-open [r (io/reader "file.txt")
            w (io/writer "file1.txt")]
  (doseq [line (line-seq r)]
    (.write w (str line "\n"))))

二进制读取

(with-open [input (new java.io.FileInputStream "image.png")
            output (new java.io.ByteArrayOutputStream)]
    (io/copy input output)
    (.toByteArray output))

二进制写入

(with-open [output (new java.io.FileOutputStream "file.bin")]
   (.write output (.getBytes "abcdefg")))

Grizzly

Never say never!