Tailing a file in Clojure?

后端 未结 3 1864
独厮守ぢ
独厮守ぢ 2021-02-03 11:09

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!

相关标签:
3条回答
  • 2021-02-03 11:34

    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.

    0 讨论(0)
  • 2021-02-03 11:35

    Something like:

    (take-last 10 (line-seq (clojure.contrib.io/reader "file")))
    
    0 讨论(0)
  • 2021-02-03 11:53

    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))
    
    0 讨论(0)
提交回复
热议问题