2010-12-02 3 views
9

Was wäre die beste Methode, um eine Datei in Clojure zu beenden? Ich habe keine Dienstprogramme gefunden, die dazu beitragen würden, aber Ideen, wie man einen erstellt, würden geschätzt werden!Eine Datei in Clojure zurückverfolgen?

Danke.

Antwort

12

Als kotarak angegeben, könnten Sie Random verwenden bis zum Ende der Datei zu suchen. Leider müssen Sie auf Änderungen warten.

eine faule Sequenz können Sie in die Linien "on-the-fly" verarbeiten:

(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:

So etwas wie tail -f /var/log/mail.log -n 0, mit doseq, so dass die Änderungen tatsächlich verbraucht werden.

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

Danke für den Zeiger! Aus irgendeinem Grund scheint dies nicht wie vorgesehen zu funktionieren - Dateiänderungen scheinen nicht erkannt zu werden! – viksit

+0

(Programm stoppt nach dem ersten Dateiwechsel) – viksit

+0

Bitte überprüfen Sie mein Update: Auch das Schreiben in die Datei ist nicht "line-buffered"? –

2

Etwas wie:

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

können Sie RandomAccessFile verwenden, um direkt an das Ende der Datei zu suchen und für Zeilenumbrüche von dort suchen. Nicht so elegant und kurz wie der take-last Ansatz, aber auch nicht O(n), was für große Dateigrößen von Bedeutung sein könnte.

Keine Lösung für tail -f, obwohl. Einige Inspiration könnte in JLogTailer gefunden werden.

Verwandte Themen