简体   繁体   中英

Tailing a file in Clojure?

What would be the best method to tail a file in Clojure? I haven't come across any utilities that would help do so, but ideas on how to build one would be appreciated!

Thanks.

As kotarak stated, you could use RandomAccessFile to seek to the end of the File. Unfortunately you have to busy-wait/sleep for changes.

Using a lazy sequence you can process the lines "on-the-fly":

(import java.io.RandomAccessFile)

(defn raf-seq
  [#^RandomAccessFile raf]
  (if-let [line (.readLine raf)]
    (lazy-seq (cons line (raf-seq raf)))
    (do (Thread/sleep 1000)
        (recur raf))))

(defn tail-seq [input]
  (let [raf (RandomAccessFile. input "r")]
    (.seek raf (.length raf))
    (raf-seq raf)))

; Read the next 10 lines
(take 10 (tail-seq "/var/log/mail.log"))

Update:

Something like tail -f /var/log/mail.log -n 0 , using doseq , so the changes are actually consumed.

(doseq [line (tail-seq "/var/log/mail.log")] (println line))

You can use RandomAccessFile to seek directly to the end of the file and search for linebreaks from there. Not as elegant and short as the take-last approach, but also not O(n) which might matter for big file sizes.

No solution for tail -f , though. Some inspiration might be found in JLogTailer .

就像是:

(take-last 10 (line-seq (clojure.contrib.io/reader "file")))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM